blob: 7f13ce21b06284b7e5c5cfa95595a47c5503ebb9 [file] [log] [blame]
Adam Cozzette501ecec2023-09-26 14:36:20 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2023 Google LLC. All rights reserved.
Adam Cozzette501ecec2023-09-26 14:36:20 -07003//
Hong Shinc482a8a2023-11-09 09:30:34 -08004// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
Hong Shin096b1392024-07-03 10:04:09 -07008#include "google/protobuf/compiler/hpb/gen_repeated_fields.h"
Adam Cozzette501ecec2023-09-26 14:36:20 -07009
10#include <string>
11#include <vector>
12
13#include "google/protobuf/descriptor.pb.h"
14#include "absl/strings/string_view.h"
Hong Shin082cf002024-10-15 12:29:42 -070015#include "google/protobuf/compiler/hpb/context.h"
Hong Shin096b1392024-07-03 10:04:09 -070016#include "google/protobuf/compiler/hpb/gen_accessors.h"
17#include "google/protobuf/compiler/hpb/gen_enums.h"
18#include "google/protobuf/compiler/hpb/gen_extensions.h"
19#include "google/protobuf/compiler/hpb/gen_utils.h"
20#include "google/protobuf/compiler/hpb/names.h"
Hong Shin090edb72024-08-06 09:55:47 -070021#include "google/protobuf/descriptor.h"
Joshua Habermanfd6d8722024-09-08 21:52:55 -070022#include "upb_generator/c/names.h"
Adam Cozzette12c7bb02023-09-28 12:54:11 -070023#include "upb_generator/common.h"
24#include "upb_generator/file_layout.h"
Adam Cozzette501ecec2023-09-26 14:36:20 -070025
Hong Shin7a2b37f2024-07-09 15:42:34 -070026namespace google::protobuf::hpb_generator {
27
Hong Shin096b1392024-07-03 10:04:09 -070028namespace protobuf = ::proto2;
Adam Cozzette501ecec2023-09-26 14:36:20 -070029
30// Adds using accessors to reuse base Access class members from a Proxy/CProxy.
31void WriteRepeatedFieldUsingAccessors(const protobuf::FieldDescriptor* field,
32 absl::string_view class_name,
33 absl::string_view resolved_field_name,
Hong Shin082cf002024-10-15 12:29:42 -070034 Context& ctx, bool read_only) {
Adam Cozzette501ecec2023-09-26 14:36:20 -070035 if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
Hong Shin082cf002024-10-15 12:29:42 -070036 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -070037 R"cc(
38 using $0Access::$1;
39 using $0Access::$1_size;
40 )cc",
41 class_name, resolved_field_name);
42 if (!read_only) {
Hong Shin082cf002024-10-15 12:29:42 -070043 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -070044 R"cc(
45 using $0Access::add_$1;
Hong Shin36075ea2024-10-09 12:44:27 -070046 using $0Access::add_alias_$1;
Adam Cozzette501ecec2023-09-26 14:36:20 -070047 using $0Access::mutable_$1;
48 )cc",
49 class_name, resolved_field_name);
50 }
51 } else {
Hong Shin082cf002024-10-15 12:29:42 -070052 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -070053 R"cc(
54 using $0Access::$1;
55 using $0Access::$1_size;
56 )cc",
57 class_name, resolved_field_name);
58 if (!read_only) {
Hong Shin082cf002024-10-15 12:29:42 -070059 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -070060 R"cc(
61 using $0Access::add_$1;
62 using $0Access::mutable_$1;
63 using $0Access::resize_$1;
64 using $0Access::set_$1;
65 )cc",
66 class_name, resolved_field_name);
67 }
68 }
69}
70
71void WriteRepeatedFieldsInMessageHeader(const protobuf::Descriptor* desc,
72 const protobuf::FieldDescriptor* field,
73 absl::string_view resolved_field_name,
74 absl::string_view resolved_upbc_name,
Hong Shin082cf002024-10-15 12:29:42 -070075 Context& ctx) {
76 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -070077 R"cc(
78 inline size_t $1_size() const {
79 size_t len;
80 $0_$2(msg_, &len);
81 return len;
82 }
83 )cc",
84 MessageName(desc), resolved_field_name, resolved_upbc_name);
85
86 if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
Hong Shin082cf002024-10-15 12:29:42 -070087 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -070088 R"cc(
89 $1 $2(size_t index) const;
Hong Shin090edb72024-08-06 09:55:47 -070090 const ::hpb::RepeatedField<const $4>::CProxy $2() const;
91 ::hpb::Ptr<::hpb::RepeatedField<$4>> mutable_$2();
Adam Cozzette501ecec2023-09-26 14:36:20 -070092 absl::StatusOr<$0> add_$2();
Hong Shin36075ea2024-10-09 12:44:27 -070093 /**
94 * Re-points submsg of repeated field to given target.
95 *
96 * REQUIRES: both messages must be in the same arena.
97 */
98 bool add_alias_$2($0 target);
Adam Cozzette501ecec2023-09-26 14:36:20 -070099 $0 mutable_$2(size_t index) const;
100 )cc",
101 MessagePtrConstType(field, /* const */ false), // $0
102 MessagePtrConstType(field, /* const */ true), // $1
103 resolved_field_name, // $2
104 resolved_upbc_name, // $3
105 MessageBaseType(field, /* maybe_const */ false) // $4
106 );
107 } else if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_STRING) {
Hong Shin082cf002024-10-15 12:29:42 -0700108 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700109 R"cc(
110 $0 $1(size_t index) const;
Hong Shin090edb72024-08-06 09:55:47 -0700111 const ::hpb::RepeatedField<$0>::CProxy $1() const;
112 ::hpb::Ptr<::hpb::RepeatedField<$0>> mutable_$1();
Adam Cozzette501ecec2023-09-26 14:36:20 -0700113 bool add_$1($0 val);
114 void set_$1(size_t index, $0 val);
115 bool resize_$1(size_t len);
116 )cc",
117 CppConstType(field), resolved_field_name);
118 } else {
Hong Shin082cf002024-10-15 12:29:42 -0700119 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700120 R"cc(
121 $0 $1(size_t index) const;
Hong Shin090edb72024-08-06 09:55:47 -0700122 const ::hpb::RepeatedField<$0>::CProxy $1() const;
123 ::hpb::Ptr<::hpb::RepeatedField<$0>> mutable_$1();
Adam Cozzette501ecec2023-09-26 14:36:20 -0700124 bool add_$1($0 val);
125 void set_$1(size_t index, $0 val);
126 bool resize_$1(size_t len);
127 )cc",
128 CppConstType(field), resolved_field_name);
129 }
130}
131
132void WriteRepeatedMessageAccessor(const protobuf::Descriptor* message,
133 const protobuf::FieldDescriptor* field,
134 const absl::string_view resolved_field_name,
135 const absl::string_view class_name,
Hong Shin082cf002024-10-15 12:29:42 -0700136 Context& ctx) {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700137 const char arena_expression[] = "arena_";
138 absl::string_view upbc_name = field->name();
Hong Shin082cf002024-10-15 12:29:42 -0700139 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700140 R"cc(
141 $1 $0::$2(size_t index) const {
142 size_t len;
143 auto* ptr = $3_$5(msg_, &len);
144 assert(index < len);
Hong Shincaa8f9d2024-08-22 12:00:45 -0700145 return ::hpb::interop::upb::MakeCHandle<$4>(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700146 (upb_Message*)*(ptr + index), arena_);
147 }
148 )cc",
149 class_name, MessagePtrConstType(field, /* is_const */ true),
150 resolved_field_name, MessageName(message),
151 MessageBaseType(field, /* maybe_const */ false), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700152 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700153 R"cc(
154 absl::StatusOr<$1> $0::add_$2() {
155 auto new_msg = $3_add_$6(msg_, $5);
156 if (!new_msg) {
Hong Shin9a24fc92024-08-20 15:20:52 -0700157 return ::hpb::MessageAllocationError();
Adam Cozzette501ecec2023-09-26 14:36:20 -0700158 }
Hong Shin36075ea2024-10-09 12:44:27 -0700159 return hpb::interop::upb::MakeHandle<$4>((upb_Message *)new_msg, $5);
160 }
161
162 bool $0::add_alias_$2($1 target) {
163 ABSL_CHECK_EQ(arena_, hpb::interop::upb::GetArena(target));
164 size_t size = 0;
165 $3_$2(msg_, &size);
166 auto elements = $3_resize_$2(msg_, size + 1, arena_);
167 if (!elements) {
168 return false;
169 }
170 elements[size] = ($9 *)hpb::interop::upb::GetMessage(target);
171 return true;
Adam Cozzette501ecec2023-09-26 14:36:20 -0700172 }
173 )cc",
174 class_name, MessagePtrConstType(field, /* const */ false),
175 resolved_field_name, MessageName(message),
176 MessageBaseType(field, /* maybe_const */ false), arena_expression,
Hong Shin36075ea2024-10-09 12:44:27 -0700177 upbc_name, ClassName(message), field->index(),
178 upb::generator::CApiMessageType(field->message_type()->full_name()));
Hong Shin082cf002024-10-15 12:29:42 -0700179 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700180 R"cc(
181 $1 $0::mutable_$2(size_t index) const {
182 size_t len;
183 auto* ptr = $3_$6(msg_, &len);
184 assert(index < len);
Hong Shind4a89952024-08-29 07:56:08 -0700185 return hpb::interop::upb::MakeHandle<$4>((upb_Message*)*(ptr + index), $5);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700186 }
187 )cc",
188 class_name, MessagePtrConstType(field, /* is_const */ false),
189 resolved_field_name, MessageName(message),
190 MessageBaseType(field, /* maybe_const */ false), arena_expression,
191 upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700192 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700193 R"cc(
Hong Shin090edb72024-08-06 09:55:47 -0700194 const ::hpb::RepeatedField<const $1>::CProxy $0::$2() const {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700195 size_t size;
196 const upb_Array* arr = _$3_$4_$5(msg_, &size);
Hong Shin090edb72024-08-06 09:55:47 -0700197 return ::hpb::RepeatedField<const $1>::CProxy(arr, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700198 };
Hong Shin090edb72024-08-06 09:55:47 -0700199 ::hpb::Ptr<::hpb::RepeatedField<$1>> $0::mutable_$2() {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700200 size_t size;
201 upb_Array* arr = _$3_$4_$6(msg_, &size, arena_);
Hong Shin090edb72024-08-06 09:55:47 -0700202 return ::hpb::RepeatedField<$1>::Proxy(arr, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700203 }
204 )cc",
Adam Cozzette12c7bb02023-09-28 12:54:11 -0700205 class_name, // $0
206 MessageBaseType(field, /* maybe_const */ false), // $1
207 resolved_field_name, // $2
208 MessageName(message), // $3
209 upbc_name, // $4
210 upb::generator::kRepeatedFieldArrayGetterPostfix, // $5
211 upb::generator::kRepeatedFieldMutableArrayGetterPostfix // $6
Adam Cozzette501ecec2023-09-26 14:36:20 -0700212 );
213}
214
215void WriteRepeatedStringAccessor(const protobuf::Descriptor* message,
216 const protobuf::FieldDescriptor* field,
217 const absl::string_view resolved_field_name,
218 const absl::string_view class_name,
Hong Shin082cf002024-10-15 12:29:42 -0700219 Context& ctx) {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700220 absl::string_view upbc_name = field->name();
Hong Shin082cf002024-10-15 12:29:42 -0700221 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700222 R"cc(
223 $1 $0::$2(size_t index) const {
224 size_t len;
225 auto* ptr = $3_mutable_$4(msg_, &len);
226 assert(index < len);
Hong Shin9d835e62024-09-12 12:34:47 -0700227 return hpb::interop::upb::FromUpbStringView(*(ptr + index));
Adam Cozzette501ecec2023-09-26 14:36:20 -0700228 }
229 )cc",
230 class_name, CppConstType(field), resolved_field_name,
231 MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700232 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700233 R"cc(
234 bool $0::resize_$1(size_t len) {
235 return $2_resize_$3(msg_, len, arena_);
236 }
237 )cc",
238 class_name, resolved_field_name, MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700239 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700240 R"cc(
241 bool $0::add_$2($1 val) {
Hong Shin86817422024-09-19 11:06:34 -0700242 return $3_add_$4(msg_,
243 hpb::interop::upb::CopyToUpbStringView(val, arena_),
244 arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700245 }
246 )cc",
247 class_name, CppConstType(field), resolved_field_name,
248 MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700249 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700250 R"cc(
251 void $0::set_$2(size_t index, $1 val) {
252 size_t len;
253 auto* ptr = $3_mutable_$4(msg_, &len);
254 assert(index < len);
Hong Shin86817422024-09-19 11:06:34 -0700255 *(ptr + index) = hpb::interop::upb::CopyToUpbStringView(val, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700256 }
257 )cc",
258 class_name, CppConstType(field), resolved_field_name,
259 MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700260 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700261 R"cc(
Hong Shin090edb72024-08-06 09:55:47 -0700262 const ::hpb::RepeatedField<$1>::CProxy $0::$2() const {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700263 size_t size;
264 const upb_Array* arr = _$3_$4_$5(msg_, &size);
Hong Shin090edb72024-08-06 09:55:47 -0700265 return ::hpb::RepeatedField<$1>::CProxy(arr, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700266 };
Hong Shin090edb72024-08-06 09:55:47 -0700267 ::hpb::Ptr<::hpb::RepeatedField<$1>> $0::mutable_$2() {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700268 size_t size;
269 upb_Array* arr = _$3_$4_$6(msg_, &size, arena_);
Hong Shin090edb72024-08-06 09:55:47 -0700270 return ::hpb::RepeatedField<$1>::Proxy(arr, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700271 }
272 )cc",
Adam Cozzette12c7bb02023-09-28 12:54:11 -0700273 class_name, // $0
274 CppConstType(field), // $1
275 resolved_field_name, // $2
276 MessageName(message), // $3
277 upbc_name, // $4
278 upb::generator::kRepeatedFieldArrayGetterPostfix, // $5
279 upb::generator::kRepeatedFieldMutableArrayGetterPostfix // $6
Adam Cozzette501ecec2023-09-26 14:36:20 -0700280 );
281}
282
283void WriteRepeatedScalarAccessor(const protobuf::Descriptor* message,
284 const protobuf::FieldDescriptor* field,
285 const absl::string_view resolved_field_name,
286 const absl::string_view class_name,
Hong Shin082cf002024-10-15 12:29:42 -0700287 Context& ctx) {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700288 absl::string_view upbc_name = field->name();
Hong Shin082cf002024-10-15 12:29:42 -0700289 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700290 R"cc(
291 $1 $0::$2(size_t index) const {
292 size_t len;
293 auto* ptr = $3_mutable_$4(msg_, &len);
294 assert(index < len);
295 return *(ptr + index);
296 }
297 )cc",
298 class_name, CppConstType(field), resolved_field_name,
299 MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700300 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700301 R"cc(
302 bool $0::resize_$1(size_t len) {
303 return $2_resize_$3(msg_, len, arena_);
304 }
305 )cc",
306 class_name, resolved_field_name, MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700307 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700308 R"cc(
309 bool $0::add_$2($1 val) { return $3_add_$4(msg_, val, arena_); }
310 )cc",
311 class_name, CppConstType(field), resolved_field_name,
312 MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700313 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700314 R"cc(
315 void $0::set_$2(size_t index, $1 val) {
316 size_t len;
317 auto* ptr = $3_mutable_$4(msg_, &len);
318 assert(index < len);
319 *(ptr + index) = val;
320 }
321 )cc",
322 class_name, CppConstType(field), resolved_field_name,
323 MessageName(message), upbc_name);
Hong Shin082cf002024-10-15 12:29:42 -0700324 ctx.EmitLegacy(
Adam Cozzette501ecec2023-09-26 14:36:20 -0700325 R"cc(
Hong Shin090edb72024-08-06 09:55:47 -0700326 const ::hpb::RepeatedField<$1>::CProxy $0::$2() const {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700327 size_t size;
328 const upb_Array* arr = _$3_$4_$5(msg_, &size);
Hong Shin090edb72024-08-06 09:55:47 -0700329 return ::hpb::RepeatedField<$1>::CProxy(arr, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700330 };
Hong Shin090edb72024-08-06 09:55:47 -0700331 ::hpb::Ptr<::hpb::RepeatedField<$1>> $0::mutable_$2() {
Adam Cozzette501ecec2023-09-26 14:36:20 -0700332 size_t size;
333 upb_Array* arr = _$3_$4_$6(msg_, &size, arena_);
Hong Shin090edb72024-08-06 09:55:47 -0700334 return ::hpb::RepeatedField<$1>::Proxy(arr, arena_);
Adam Cozzette501ecec2023-09-26 14:36:20 -0700335 }
336 )cc",
Adam Cozzette12c7bb02023-09-28 12:54:11 -0700337 class_name, // $0
338 CppConstType(field), // $1
339 resolved_field_name, // $2
340 MessageName(message), // $3
341 upbc_name, // $4
342 upb::generator::kRepeatedFieldArrayGetterPostfix, // $5
343 upb::generator::kRepeatedFieldMutableArrayGetterPostfix // $6
Adam Cozzette501ecec2023-09-26 14:36:20 -0700344 );
345}
346
Hong Shin7a2b37f2024-07-09 15:42:34 -0700347} // namespace protobuf
348} // namespace google::hpb_generator