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