1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/compiler/cpp/cpp_message_field.h>
36 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
37 #include <google/protobuf/io/printer.h>
38
39 #include <google/protobuf/stubs/strutil.h>
40
41 namespace google {
42 namespace protobuf {
43 namespace compiler {
44 namespace cpp {
45
46 namespace {
ReinterpretCast(const std::string & type,const std::string & expression,bool implicit_weak_field)47 std::string ReinterpretCast(const std::string& type,
48 const std::string& expression,
49 bool implicit_weak_field) {
50 if (implicit_weak_field) {
51 return "reinterpret_cast< " + type + " >(" + expression + ")";
52 } else {
53 return expression;
54 }
55 }
56
SetMessageVariables(const FieldDescriptor * descriptor,const Options & options,bool implicit_weak,std::map<std::string,std::string> * variables)57 void SetMessageVariables(const FieldDescriptor* descriptor,
58 const Options& options, bool implicit_weak,
59 std::map<std::string, std::string>* variables) {
60 SetCommonFieldVariables(descriptor, variables, options);
61 (*variables)["type"] = FieldMessageTypeName(descriptor, options);
62 (*variables)["casted_member"] = ReinterpretCast(
63 (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak);
64 (*variables)["type_default_instance"] =
65 QualifiedDefaultInstanceName(descriptor->message_type(), options);
66 (*variables)["type_default_instance_ptr"] =
67 QualifiedDefaultInstancePtr(descriptor->message_type(), options);
68 (*variables)["type_reference_function"] =
69 implicit_weak ? (" ::" + (*variables)["proto_ns"] +
70 "::internal::StrongReference(reinterpret_cast<const " +
71 (*variables)["type"] + "&>(\n" +
72 (*variables)["type_default_instance"] + "));\n")
73 : "";
74 // NOTE: Escaped here to unblock proto1->proto2 migration.
75 // TODO(liujisi): Extend this to apply for other conflicting methods.
76 (*variables)["release_name"] =
77 SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
78 (*variables)["full_name"] = descriptor->full_name();
79 }
80
81 } // namespace
82
83 // ===================================================================
84
MessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)85 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
86 const Options& options,
87 MessageSCCAnalyzer* scc_analyzer)
88 : FieldGenerator(descriptor, options),
89 implicit_weak_field_(
90 IsImplicitWeakField(descriptor, options, scc_analyzer)) {
91 SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
92 }
93
~MessageFieldGenerator()94 MessageFieldGenerator::~MessageFieldGenerator() {}
95
GeneratePrivateMembers(io::Printer * printer) const96 void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
97 Formatter format(printer, variables_);
98 if (implicit_weak_field_) {
99 format("::$proto_ns$::MessageLite* $name$_;\n");
100 } else {
101 format("$type$* $name$_;\n");
102 }
103 }
104
GenerateAccessorDeclarations(io::Printer * printer) const105 void MessageFieldGenerator::GenerateAccessorDeclarations(
106 io::Printer* printer) const {
107 Formatter format(printer, variables_);
108 if (IsFieldStripped(descriptor_, options_)) {
109 format(
110 "$deprecated_attr$const $type$& ${1$$name$$}$() const { "
111 "__builtin_trap(); }\n"
112 "PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* "
113 "${1$$release_name$$}$() { "
114 "__builtin_trap(); }\n"
115 "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
116 "__builtin_trap(); }\n"
117 "$deprecated_attr$void ${1$set_allocated_$name$$}$"
118 "($type$* $name$) { __builtin_trap(); }\n"
119 "$deprecated_attr$void "
120 "${1$unsafe_arena_set_allocated_$name$$}$(\n"
121 " $type$* $name$) { __builtin_trap(); }\n"
122 "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
123 "__builtin_trap(); }\n",
124 descriptor_);
125 return;
126 }
127 format(
128 "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
129 "PROTOBUF_MUST_USE_RESULT $deprecated_attr$$type$* "
130 "${1$$release_name$$}$();\n"
131 "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
132 "$deprecated_attr$void ${1$set_allocated_$name$$}$"
133 "($type$* $name$);\n",
134 descriptor_);
135 if (!IsFieldStripped(descriptor_, options_)) {
136 format(
137 "private:\n"
138 "const $type$& ${1$_internal_$name$$}$() const;\n"
139 "$type$* ${1$_internal_mutable_$name$$}$();\n"
140 "public:\n",
141 descriptor_);
142 }
143 format(
144 "$deprecated_attr$void "
145 "${1$unsafe_arena_set_allocated_$name$$}$(\n"
146 " $type$* $name$);\n"
147 "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
148 descriptor_);
149 }
150
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const151 void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
152 io::Printer* printer) const {
153 }
154
GenerateInlineAccessorDefinitions(io::Printer * printer) const155 void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
156 io::Printer* printer) const {
157 Formatter format(printer, variables_);
158 format(
159 "inline const $type$& $classname$::_internal_$name$() const {\n"
160 "$type_reference_function$"
161 " const $type$* p = $casted_member$;\n"
162 " return p != nullptr ? *p : reinterpret_cast<const $type$&>(\n"
163 " $type_default_instance$);\n"
164 "}\n"
165 "inline const $type$& $classname$::$name$() const {\n"
166 "$annotate_get$"
167 " // @@protoc_insertion_point(field_get:$full_name$)\n"
168 " return _internal_$name$();\n"
169 "}\n");
170
171 format(
172 "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
173 " $type$* $name$) {\n"
174 // If we're not on an arena, free whatever we were holding before.
175 // (If we are on arena, we can just forget the earlier pointer.)
176 " if (GetArenaForAllocation() == nullptr) {\n"
177 " delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
178 " }\n");
179 if (implicit_weak_field_) {
180 format(
181 " $name$_ = "
182 "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
183 } else {
184 format(" $name$_ = $name$;\n");
185 }
186 format(
187 " if ($name$) {\n"
188 " $set_hasbit$\n"
189 " } else {\n"
190 " $clear_hasbit$\n"
191 " }\n"
192 "$annotate_set$"
193 " // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
194 ":$full_name$)\n"
195 "}\n");
196 format(
197 "inline $type$* $classname$::$release_name$() {\n"
198 "$type_reference_function$"
199 "$annotate_release$"
200 " $clear_hasbit$\n"
201 " $type$* temp = $casted_member$;\n"
202 " $name$_ = nullptr;\n"
203 "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n"
204 " auto* old = reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n"
205 " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
206 " if (GetArenaForAllocation() == nullptr) { delete old; }\n"
207 "#else // PROTOBUF_FORCE_COPY_IN_RELEASE\n"
208 " if (GetArenaForAllocation() != nullptr) {\n"
209 " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
210 " }\n"
211 "#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE\n"
212 " return temp;\n"
213 "}\n"
214 "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
215 "$annotate_release$"
216 " // @@protoc_insertion_point(field_release:$full_name$)\n"
217 "$type_reference_function$"
218 " $clear_hasbit$\n"
219 " $type$* temp = $casted_member$;\n"
220 " $name$_ = nullptr;\n"
221 " return temp;\n"
222 "}\n");
223
224 format(
225 "inline $type$* $classname$::_internal_mutable_$name$() {\n"
226 "$type_reference_function$"
227 " $set_hasbit$\n"
228 " if ($name$_ == nullptr) {\n"
229 " auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n");
230 if (implicit_weak_field_) {
231 format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
232 } else {
233 format(" $name$_ = p;\n");
234 }
235 format(
236 " }\n"
237 " return $casted_member$;\n"
238 "}\n"
239 "inline $type$* $classname$::mutable_$name$() {\n"
240 " $type$* _msg = _internal_mutable_$name$();\n"
241 "$annotate_mutable$"
242 " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
243 " return _msg;\n"
244 "}\n");
245
246 // We handle the most common case inline, and delegate less common cases to
247 // the slow fallback function.
248 format(
249 "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
250 " ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n");
251 format(" if (message_arena == nullptr) {\n");
252 if (IsCrossFileMessage(descriptor_)) {
253 format(
254 " delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
255 } else {
256 format(" delete $name$_;\n");
257 }
258 format(
259 " }\n"
260 " if ($name$) {\n");
261 if (IsCrossFileMessage(descriptor_)) {
262 // We have to read the arena through the virtual method, because the type
263 // isn't defined in this file.
264 format(
265 " ::$proto_ns$::Arena* submessage_arena =\n"
266 " ::$proto_ns$::Arena::InternalHelper<\n"
267 " ::$proto_ns$::MessageLite>::GetOwningArena(\n"
268 " reinterpret_cast<::$proto_ns$::MessageLite*>("
269 "$name$));\n");
270 } else {
271 format(
272 " ::$proto_ns$::Arena* submessage_arena =\n"
273 " ::$proto_ns$::Arena::InternalHelper<$type$>::GetOwningArena("
274 "$name$);\n");
275 }
276 format(
277 " if (message_arena != submessage_arena) {\n"
278 " $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
279 " message_arena, $name$, submessage_arena);\n"
280 " }\n"
281 " $set_hasbit$\n"
282 " } else {\n"
283 " $clear_hasbit$\n"
284 " }\n");
285 if (implicit_weak_field_) {
286 format(" $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
287 } else {
288 format(" $name$_ = $name$;\n");
289 }
290 format(
291 "$annotate_set$"
292 " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
293 "}\n");
294 }
295
GenerateInternalAccessorDeclarations(io::Printer * printer) const296 void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
297 io::Printer* printer) const {
298 Formatter format(printer, variables_);
299 if (implicit_weak_field_) {
300 format(
301 "static const ::$proto_ns$::MessageLite& $name$("
302 "const $classname$* msg);\n"
303 "static ::$proto_ns$::MessageLite* mutable_$name$("
304 "$classname$* msg);\n");
305 } else {
306 format("static const $type$& $name$(const $classname$* msg);\n");
307 }
308 }
309
GenerateInternalAccessorDefinitions(io::Printer * printer) const310 void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
311 io::Printer* printer) const {
312 // In theory, these accessors could be inline in _Internal. However, in
313 // practice, the linker is then not able to throw them out making implicit
314 // weak dependencies not work at all.
315 Formatter format(printer, variables_);
316 if (implicit_weak_field_) {
317 // These private accessors are used by MergeFrom and
318 // MergePartialFromCodedStream, and their purpose is to provide access to
319 // the field without creating a strong dependency on the message type.
320 format(
321 "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
322 " const $classname$* msg) {\n"
323 " if (msg->$name$_ != nullptr) {\n"
324 " return *msg->$name$_;\n"
325 " } else if ($type_default_instance_ptr$ != nullptr) {\n"
326 " return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
327 " $type_default_instance_ptr$);\n"
328 " } else {\n"
329 " return "
330 "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
331 " }\n"
332 "}\n");
333 format(
334 "::$proto_ns$::MessageLite*\n"
335 "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
336 if (HasHasbit(descriptor_)) {
337 format(" msg->$set_hasbit$\n");
338 }
339 format(
340 " if (msg->$name$_ == nullptr) {\n"
341 " if ($type_default_instance_ptr$ == nullptr) {\n"
342 " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
343 " ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
344 " msg->GetArenaForAllocation());\n"
345 " } else {\n"
346 " msg->$name$_ = \n"
347 " reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
348 " $type_default_instance_ptr$)->New(\n"
349 " msg->GetArenaForAllocation());\n"
350 " }\n"
351 " }\n"
352 " return msg->$name$_;\n"
353 "}\n");
354 } else {
355 // This inline accessor directly returns member field and is used in
356 // Serialize such that AFDO profile correctly captures access information to
357 // message fields under serialize.
358 format(
359 "const $type$&\n"
360 "$classname$::_Internal::$name$(const $classname$* msg) {\n"
361 " return *msg->$field_member$;\n"
362 "}\n");
363 }
364 }
365
GenerateClearingCode(io::Printer * printer) const366 void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
367 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
368
369 Formatter format(printer, variables_);
370 if (!HasHasbit(descriptor_)) {
371 // If we don't have has-bits, message presence is indicated only by ptr !=
372 // NULL. Thus on clear, we need to delete the object.
373 format(
374 "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n"
375 " delete $name$_;\n"
376 "}\n"
377 "$name$_ = nullptr;\n");
378 } else {
379 format("if ($name$_ != nullptr) $name$_->Clear();\n");
380 }
381 }
382
GenerateMessageClearingCode(io::Printer * printer) const383 void MessageFieldGenerator::GenerateMessageClearingCode(
384 io::Printer* printer) const {
385 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
386
387 Formatter format(printer, variables_);
388 if (!HasHasbit(descriptor_)) {
389 // If we don't have has-bits, message presence is indicated only by ptr !=
390 // NULL. Thus on clear, we need to delete the object.
391 format(
392 "if (GetArenaForAllocation() == nullptr && $name$_ != nullptr) {\n"
393 " delete $name$_;\n"
394 "}\n"
395 "$name$_ = nullptr;\n");
396 } else {
397 format(
398 "$DCHK$($name$_ != nullptr);\n"
399 "$name$_->Clear();\n");
400 }
401 }
402
GenerateMergingCode(io::Printer * printer) const403 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
404 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
405
406 Formatter format(printer, variables_);
407 if (implicit_weak_field_) {
408 format(
409 "_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
410 " _Internal::$name$(&from));\n");
411 } else {
412 format(
413 "_internal_mutable_$name$()->$type$::MergeFrom(from._internal_$name$())"
414 ";\n");
415 }
416 }
417
GenerateSwappingCode(io::Printer * printer) const418 void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
419 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
420
421 Formatter format(printer, variables_);
422 format("swap($name$_, other->$name$_);\n");
423 }
424
GenerateDestructorCode(io::Printer * printer) const425 void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
426 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
427
428 Formatter format(printer, variables_);
429 if (options_.opensource_runtime) {
430 // TODO(gerbens) Remove this when we don't need to destruct default
431 // instances. In google3 a default instance will never get deleted so we
432 // don't need to worry about that but in opensource protobuf default
433 // instances are deleted in shutdown process and we need to take special
434 // care when handling them.
435 format("if (this != internal_default_instance()) ");
436 }
437 format("delete $name$_;\n");
438 }
439
GenerateConstructorCode(io::Printer * printer) const440 void MessageFieldGenerator::GenerateConstructorCode(
441 io::Printer* printer) const {
442 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
443
444 Formatter format(printer, variables_);
445 format("$name$_ = nullptr;\n");
446 }
447
GenerateCopyConstructorCode(io::Printer * printer) const448 void MessageFieldGenerator::GenerateCopyConstructorCode(
449 io::Printer* printer) const {
450 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
451
452 Formatter format(printer, variables_);
453 format(
454 "if (from._internal_has_$name$()) {\n"
455 " $name$_ = new $type$(*from.$name$_);\n"
456 "} else {\n"
457 " $name$_ = nullptr;\n"
458 "}\n");
459 }
460
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const461 void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
462 io::Printer* printer) const {
463 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
464
465 Formatter format(printer, variables_);
466 format(
467 "target = stream->EnsureSpace(target);\n"
468 "target = ::$proto_ns$::internal::WireFormatLite::\n"
469 " InternalWrite$declared_type$(\n"
470 " $number$, _Internal::$name$(this), target, stream);\n");
471 }
472
GenerateByteSize(io::Printer * printer) const473 void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
474 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
475
476 Formatter format(printer, variables_);
477 format(
478 "total_size += $tag_size$ +\n"
479 " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
480 " *$field_member$);\n");
481 }
482
GenerateConstinitInitializer(io::Printer * printer) const483 void MessageFieldGenerator::GenerateConstinitInitializer(
484 io::Printer* printer) const {
485 Formatter format(printer, variables_);
486 format("$name$_(nullptr)");
487 }
488
489 // ===================================================================
490
MessageOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)491 MessageOneofFieldGenerator::MessageOneofFieldGenerator(
492 const FieldDescriptor* descriptor, const Options& options,
493 MessageSCCAnalyzer* scc_analyzer)
494 : MessageFieldGenerator(descriptor, options, scc_analyzer) {
495 SetCommonOneofFieldVariables(descriptor, &variables_);
496 }
497
~MessageOneofFieldGenerator()498 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
499
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const500 void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
501 io::Printer* printer) const {
502 Formatter format(printer, variables_);
503 format(
504 "void $classname$::set_allocated_$name$($type$* $name$) {\n"
505 " ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"
506 " clear_$oneof_name$();\n"
507 " if ($name$) {\n");
508 if (descriptor_->file() != descriptor_->message_type()->file()) {
509 // We have to read the arena through the virtual method, because the type
510 // isn't defined in this file.
511 format(
512 " ::$proto_ns$::Arena* submessage_arena =\n"
513 " ::$proto_ns$::Arena::InternalHelper<\n"
514 " ::$proto_ns$::MessageLite>::GetOwningArena(\n"
515 " reinterpret_cast<::$proto_ns$::MessageLite*>("
516 "$name$));\n");
517 } else {
518 format(
519 " ::$proto_ns$::Arena* submessage_arena =\n"
520 " ::$proto_ns$::Arena::InternalHelper<"
521 "$type$>::GetOwningArena($name$);\n");
522 }
523 format(
524 " if (message_arena != submessage_arena) {\n"
525 " $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
526 " message_arena, $name$, submessage_arena);\n"
527 " }\n"
528 " set_has_$name$();\n"
529 " $field_member$ = $name$;\n"
530 " }\n"
531 "$annotate_set$"
532 " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
533 "}\n");
534 }
535
GenerateInlineAccessorDefinitions(io::Printer * printer) const536 void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
537 io::Printer* printer) const {
538 Formatter format(printer, variables_);
539 format(
540 "inline $type$* $classname$::$release_name$() {\n"
541 "$annotate_release$"
542 " // @@protoc_insertion_point(field_release:$full_name$)\n"
543 " if (_internal_has_$name$()) {\n"
544 " clear_has_$oneof_name$();\n"
545 " $type$* temp = $field_member$;\n"
546 " if (GetArenaForAllocation() != nullptr) {\n"
547 " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
548 " }\n"
549 " $field_member$ = nullptr;\n"
550 " return temp;\n"
551 " } else {\n"
552 " return nullptr;\n"
553 " }\n"
554 "}\n");
555
556 format(
557 "inline const $type$& $classname$::_internal_$name$() const {\n"
558 " return _internal_has_$name$()\n"
559 " ? *$field_member$\n"
560 " : reinterpret_cast< $type$&>($type_default_instance$);\n"
561 "}\n"
562 "inline const $type$& $classname$::$name$() const {\n"
563 "$annotate_get$"
564 " // @@protoc_insertion_point(field_get:$full_name$)\n"
565 " return _internal_$name$();\n"
566 "}\n"
567 "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
568 "$annotate_release$"
569 " // @@protoc_insertion_point(field_unsafe_arena_release"
570 ":$full_name$)\n"
571 " if (_internal_has_$name$()) {\n"
572 " clear_has_$oneof_name$();\n"
573 " $type$* temp = $field_member$;\n"
574 " $field_member$ = nullptr;\n"
575 " return temp;\n"
576 " } else {\n"
577 " return nullptr;\n"
578 " }\n"
579 "}\n"
580 "inline void $classname$::unsafe_arena_set_allocated_$name$"
581 "($type$* $name$) {\n"
582 // We rely on the oneof clear method to free the earlier contents of
583 // this oneof. We can directly use the pointer we're given to set the
584 // new value.
585 " clear_$oneof_name$();\n"
586 " if ($name$) {\n"
587 " set_has_$name$();\n"
588 " $field_member$ = $name$;\n"
589 " }\n"
590 "$annotate_set$"
591 " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
592 "$full_name$)\n"
593 "}\n"
594 "inline $type$* $classname$::_internal_mutable_$name$() {\n"
595 " if (!_internal_has_$name$()) {\n"
596 " clear_$oneof_name$();\n"
597 " set_has_$name$();\n"
598 " $field_member$ = CreateMaybeMessage< $type$ "
599 ">(GetArenaForAllocation());\n"
600 " }\n"
601 " return $field_member$;\n"
602 "}\n"
603 "inline $type$* $classname$::mutable_$name$() {\n"
604 " $type$* _msg = _internal_mutable_$name$();\n"
605 "$annotate_mutable$"
606 " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
607 " return _msg;\n"
608 "}\n");
609 }
610
GenerateClearingCode(io::Printer * printer) const611 void MessageOneofFieldGenerator::GenerateClearingCode(
612 io::Printer* printer) const {
613 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
614
615 Formatter format(printer, variables_);
616 format(
617 "if (GetArenaForAllocation() == nullptr) {\n"
618 " delete $field_member$;\n"
619 "}\n");
620 }
621
GenerateMessageClearingCode(io::Printer * printer) const622 void MessageOneofFieldGenerator::GenerateMessageClearingCode(
623 io::Printer* printer) const {
624 GenerateClearingCode(printer);
625 }
626
GenerateSwappingCode(io::Printer * printer) const627 void MessageOneofFieldGenerator::GenerateSwappingCode(
628 io::Printer* printer) const {
629 // Don't print any swapping code. Swapping the union will swap this field.
630 }
631
GenerateDestructorCode(io::Printer * printer) const632 void MessageOneofFieldGenerator::GenerateDestructorCode(
633 io::Printer* printer) const {
634 // We inherit from MessageFieldGenerator, so we need to override the default
635 // behavior.
636 }
637
GenerateConstructorCode(io::Printer * printer) const638 void MessageOneofFieldGenerator::GenerateConstructorCode(
639 io::Printer* printer) const {
640 // Don't print any constructor code. The field is in a union. We allocate
641 // space only when this field is used.
642 }
643
644 // ===================================================================
645
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)646 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
647 const FieldDescriptor* descriptor, const Options& options,
648 MessageSCCAnalyzer* scc_analyzer)
649 : FieldGenerator(descriptor, options),
650 implicit_weak_field_(
651 IsImplicitWeakField(descriptor, options, scc_analyzer)) {
652 SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
653 }
654
~RepeatedMessageFieldGenerator()655 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
656
GeneratePrivateMembers(io::Printer * printer) const657 void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
658 io::Printer* printer) const {
659 Formatter format(printer, variables_);
660 if (implicit_weak_field_) {
661 format("::$proto_ns$::WeakRepeatedPtrField< $type$ > $name$_;\n");
662 } else {
663 format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
664 }
665 }
666
GenerateAccessorDeclarations(io::Printer * printer) const667 void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
668 io::Printer* printer) const {
669 Formatter format(printer, variables_);
670 if (IsFieldStripped(descriptor_, options_)) {
671 format(
672 "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
673 "__builtin_trap(); }\n"
674 "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
675 " ${1$mutable_$name$$}$() { __builtin_trap(); }\n"
676 "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { "
677 "__builtin_trap(); }\n"
678 "$deprecated_attr$$type$* ${1$add_$name$$}$() { "
679 "__builtin_trap(); }\n"
680 "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
681 " ${1$$name$$}$() const { __builtin_trap(); }\n",
682 descriptor_);
683 return;
684 }
685 format(
686 "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
687 "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
688 " ${1$mutable_$name$$}$();\n",
689 descriptor_);
690 if (!IsFieldStripped(descriptor_, options_)) {
691 format(
692 "private:\n"
693 "const $type$& ${1$_internal_$name$$}$(int index) const;\n"
694 "$type$* ${1$_internal_add_$name$$}$();\n"
695 "public:\n",
696 descriptor_);
697 }
698 format(
699 "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
700 "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
701 "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
702 " ${1$$name$$}$() const;\n",
703 descriptor_);
704 }
705
GenerateInlineAccessorDefinitions(io::Printer * printer) const706 void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
707 io::Printer* printer) const {
708 Formatter format(printer, variables_);
709 format.Set("weak", implicit_weak_field_ ? ".weak" : "");
710
711 format(
712 "inline $type$* $classname$::mutable_$name$(int index) {\n"
713 "$annotate_mutable$"
714 // TODO(dlj): move insertion points
715 " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
716 "$type_reference_function$"
717 " return $name$_$weak$.Mutable(index);\n"
718 "}\n"
719 "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
720 "$classname$::mutable_$name$() {\n"
721 "$annotate_mutable_list$"
722 " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
723 "$type_reference_function$"
724 " return &$name$_$weak$;\n"
725 "}\n");
726
727 if (options_.safe_boundary_check) {
728 format(
729 "inline const $type$& $classname$::_internal_$name$(int index) const "
730 "{\n"
731 " return $name$_$weak$.InternalCheckedGet(index,\n"
732 " reinterpret_cast<const $type$&>($type_default_instance$));\n"
733 "}\n");
734 } else {
735 format(
736 "inline const $type$& $classname$::_internal_$name$(int index) const "
737 "{\n"
738 "$type_reference_function$"
739 " return $name$_$weak$.Get(index);\n"
740 "}\n");
741 }
742
743 format(
744 "inline const $type$& $classname$::$name$(int index) const {\n"
745 "$annotate_get$"
746 " // @@protoc_insertion_point(field_get:$full_name$)\n"
747 " return _internal_$name$(index);\n"
748 "}\n"
749 "inline $type$* $classname$::_internal_add_$name$() {\n"
750 " return $name$_$weak$.Add();\n"
751 "}\n"
752 "inline $type$* $classname$::add_$name$() {\n"
753 " $type$* _add = _internal_add_$name$();\n"
754 "$annotate_add_mutable$"
755 " // @@protoc_insertion_point(field_add:$full_name$)\n"
756 " return _add;\n"
757 "}\n");
758
759 format(
760 "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
761 "$classname$::$name$() const {\n"
762 "$annotate_list$"
763 " // @@protoc_insertion_point(field_list:$full_name$)\n"
764 "$type_reference_function$"
765 " return $name$_$weak$;\n"
766 "}\n");
767 }
768
GenerateClearingCode(io::Printer * printer) const769 void RepeatedMessageFieldGenerator::GenerateClearingCode(
770 io::Printer* printer) const {
771 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
772
773 Formatter format(printer, variables_);
774 format("$name$_.Clear();\n");
775 }
776
GenerateMergingCode(io::Printer * printer) const777 void RepeatedMessageFieldGenerator::GenerateMergingCode(
778 io::Printer* printer) const {
779 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
780
781 Formatter format(printer, variables_);
782 format("$name$_.MergeFrom(from.$name$_);\n");
783 }
784
GenerateSwappingCode(io::Printer * printer) const785 void RepeatedMessageFieldGenerator::GenerateSwappingCode(
786 io::Printer* printer) const {
787 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
788
789 Formatter format(printer, variables_);
790 format("$name$_.InternalSwap(&other->$name$_);\n");
791 }
792
GenerateConstructorCode(io::Printer * printer) const793 void RepeatedMessageFieldGenerator::GenerateConstructorCode(
794 io::Printer* printer) const {
795 // Not needed for repeated fields.
796 }
797
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const798 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
799 io::Printer* printer) const {
800 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
801
802 Formatter format(printer, variables_);
803 if (implicit_weak_field_) {
804 format(
805 "for (auto it = this->$name$_.pointer_begin(),\n"
806 " end = this->$name$_.pointer_end(); it < end; ++it) {\n"
807 " target = stream->EnsureSpace(target);\n"
808 " target = ::$proto_ns$::internal::WireFormatLite::\n"
809 " InternalWrite$declared_type$($number$, **it, target, stream);\n"
810 "}\n");
811 } else {
812 format(
813 "for (unsigned int i = 0,\n"
814 " n = static_cast<unsigned int>(this->_internal_$name$_size()); i < "
815 "n; i++) "
816 "{\n"
817 " target = stream->EnsureSpace(target);\n"
818 " target = ::$proto_ns$::internal::WireFormatLite::\n"
819 " InternalWrite$declared_type$($number$, "
820 "this->_internal_$name$(i), target, stream);\n"
821 "}\n");
822 }
823 }
824
GenerateByteSize(io::Printer * printer) const825 void RepeatedMessageFieldGenerator::GenerateByteSize(
826 io::Printer* printer) const {
827 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
828
829 Formatter format(printer, variables_);
830 format(
831 "total_size += $tag_size$UL * this->_internal_$name$_size();\n"
832 "for (const auto& msg : this->$name$_) {\n"
833 " total_size +=\n"
834 " ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
835 "}\n");
836 }
837
GenerateConstinitInitializer(io::Printer * printer) const838 void RepeatedMessageFieldGenerator::GenerateConstinitInitializer(
839 io::Printer* printer) const {
840 Formatter format(printer, variables_);
841 format("$name$_()");
842 }
843
844 } // namespace cpp
845 } // namespace compiler
846 } // namespace protobuf
847 } // namespace google
848