• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37 #include <google/protobuf/io/printer.h>
38 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
39 
40 #include <google/protobuf/stubs/strutil.h>
41 
42 namespace google {
43 namespace protobuf {
44 namespace compiler {
45 namespace cpp {
46 
47 namespace {
ReinterpretCast(const std::string & type,const std::string & expression,bool implicit_weak_field)48 std::string ReinterpretCast(const std::string& type,
49                             const std::string& expression,
50                             bool implicit_weak_field) {
51   if (implicit_weak_field) {
52     return "reinterpret_cast< " + type + " >(" + expression + ")";
53   } else {
54     return expression;
55   }
56 }
57 
SetMessageVariables(const FieldDescriptor * descriptor,const Options & options,bool implicit_weak,std::map<std::string,std::string> * variables)58 void SetMessageVariables(const FieldDescriptor* descriptor,
59                          const Options& options, bool implicit_weak,
60                          std::map<std::string, std::string>* variables) {
61   SetCommonFieldVariables(descriptor, variables, options);
62   (*variables)["type"] = FieldMessageTypeName(descriptor, options);
63   (*variables)["casted_member"] = ReinterpretCast(
64       (*variables)["type"] + "*", (*variables)["field"], implicit_weak);
65   (*variables)["casted_member_const"] =
66       ReinterpretCast("const " + (*variables)["type"] + "&",
67                       "*" + (*variables)["field"], implicit_weak);
68   (*variables)["type_default_instance"] =
69       QualifiedDefaultInstanceName(descriptor->message_type(), options);
70   (*variables)["type_default_instance_ptr"] = ReinterpretCast(
71       "const ::PROTOBUF_NAMESPACE_ID::MessageLite*",
72       QualifiedDefaultInstancePtr(descriptor->message_type(), options),
73       implicit_weak);
74   (*variables)["type_reference_function"] =
75       implicit_weak ? ("  ::" + (*variables)["proto_ns"] +
76                        "::internal::StrongReference(reinterpret_cast<const " +
77                        (*variables)["type"] + "&>(\n" +
78                        (*variables)["type_default_instance"] + "));\n")
79                     : "";
80   // NOTE: Escaped here to unblock proto1->proto2 migration.
81   // TODO(liujisi): Extend this to apply for other conflicting methods.
82   (*variables)["release_name"] =
83       SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
84   (*variables)["full_name"] = descriptor->full_name();
85 }
86 
87 }  // namespace
88 
89 // ===================================================================
90 
MessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)91 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
92                                              const Options& options,
93                                              MessageSCCAnalyzer* scc_analyzer)
94     : FieldGenerator(descriptor, options),
95       implicit_weak_field_(
96           IsImplicitWeakField(descriptor, options, scc_analyzer)),
97       has_required_fields_(
98           scc_analyzer->HasRequiredFields(descriptor->message_type())) {
99   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
100 }
101 
~MessageFieldGenerator()102 MessageFieldGenerator::~MessageFieldGenerator() {}
103 
GeneratePrivateMembers(io::Printer * printer) const104 void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
105   Formatter format(printer, variables_);
106   if (implicit_weak_field_) {
107     format("::$proto_ns$::MessageLite* $name$_;\n");
108   } else {
109     format("$type$* $name$_;\n");
110   }
111 }
112 
GenerateAccessorDeclarations(io::Printer * printer) const113 void MessageFieldGenerator::GenerateAccessorDeclarations(
114     io::Printer* printer) const {
115   Formatter format(printer, variables_);
116   if (IsFieldStripped(descriptor_, options_)) {
117     format(
118         "$deprecated_attr$const $type$& ${1$$name$$}$() const { "
119         "__builtin_trap(); }\n"
120         "PROTOBUF_NODISCARD $deprecated_attr$$type$* "
121         "${1$$release_name$$}$() { "
122         "__builtin_trap(); }\n"
123         "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
124         "__builtin_trap(); }\n"
125         "$deprecated_attr$void ${1$set_allocated_$name$$}$"
126         "($type$* $name$) { __builtin_trap(); }\n"
127         "$deprecated_attr$void "
128         "${1$unsafe_arena_set_allocated_$name$$}$(\n"
129         "    $type$* $name$) { __builtin_trap(); }\n"
130         "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
131         "__builtin_trap(); }\n",
132         descriptor_);
133     return;
134   }
135   format(
136       "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
137       "PROTOBUF_NODISCARD $deprecated_attr$$type$* "
138       "${1$$release_name$$}$();\n"
139       "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
140       "$deprecated_attr$void ${1$set_allocated_$name$$}$"
141       "($type$* $name$);\n",
142       descriptor_);
143   if (!IsFieldStripped(descriptor_, options_)) {
144     format(
145         "private:\n"
146         "const $type$& ${1$_internal_$name$$}$() const;\n"
147         "$type$* ${1$_internal_mutable_$name$$}$();\n"
148         "public:\n",
149         descriptor_);
150   }
151   format(
152       "$deprecated_attr$void "
153       "${1$unsafe_arena_set_allocated_$name$$}$(\n"
154       "    $type$* $name$);\n"
155       "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
156       descriptor_);
157 }
158 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const159 void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
160     io::Printer* printer) const {
161 }
162 
GenerateInlineAccessorDefinitions(io::Printer * printer) const163 void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
164     io::Printer* printer) const {
165   Formatter format(printer, variables_);
166   format(
167       "inline const $type$& $classname$::_internal_$name$() const {\n"
168       "$type_reference_function$"
169       "  const $type$* p = $casted_member$;\n"
170       "  return p != nullptr ? *p : reinterpret_cast<const $type$&>(\n"
171       "      $type_default_instance$);\n"
172       "}\n"
173       "inline const $type$& $classname$::$name$() const {\n"
174       "$annotate_get$"
175       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
176       "  return _internal_$name$();\n"
177       "}\n");
178 
179   format(
180       "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
181       "    $type$* $name$) {\n"
182       // If we're not on an arena, free whatever we were holding before.
183       // (If we are on arena, we can just forget the earlier pointer.)
184       "  if (GetArenaForAllocation() == nullptr) {\n"
185       "    delete reinterpret_cast<::$proto_ns$::MessageLite*>($field$);\n"
186       "  }\n");
187   if (implicit_weak_field_) {
188     format(
189         "  $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
190   } else {
191     format("  $field$ = $name$;\n");
192   }
193   format(
194       "  if ($name$) {\n"
195       "    $set_hasbit$\n"
196       "  } else {\n"
197       "    $clear_hasbit$\n"
198       "  }\n"
199       "$annotate_set$"
200       "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
201       ":$full_name$)\n"
202       "}\n");
203   format(
204       "inline $type$* $classname$::$release_name$() {\n"
205       "$type_reference_function$"
206       "$annotate_release$"
207       "  $clear_hasbit$\n"
208       "  $type$* temp = $casted_member$;\n"
209       "  $field$ = nullptr;\n"
210       "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n"
211       "  auto* old =  reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n"
212       "  temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
213       "  if (GetArenaForAllocation() == nullptr) { delete old; }\n"
214       "#else  // PROTOBUF_FORCE_COPY_IN_RELEASE\n"
215       "  if (GetArenaForAllocation() != nullptr) {\n"
216       "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
217       "  }\n"
218       "#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE\n"
219       "  return temp;\n"
220       "}\n"
221       "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
222       "$annotate_release$"
223       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
224       "$type_reference_function$"
225       "  $clear_hasbit$\n"
226       "  $type$* temp = $casted_member$;\n"
227       "  $field$ = nullptr;\n"
228       "  return temp;\n"
229       "}\n");
230 
231   format(
232       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
233       "$type_reference_function$"
234       "  $set_hasbit$\n"
235       "  if ($field$ == nullptr) {\n"
236       "    auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n");
237   if (implicit_weak_field_) {
238     format("    $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
239   } else {
240     format("    $field$ = p;\n");
241   }
242   format(
243       "  }\n"
244       "  return $casted_member$;\n"
245       "}\n"
246       "inline $type$* $classname$::mutable_$name$() {\n"
247       "  $type$* _msg = _internal_mutable_$name$();\n"
248       "$annotate_mutable$"
249       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
250       "  return _msg;\n"
251       "}\n");
252 
253   // We handle the most common case inline, and delegate less common cases to
254   // the slow fallback function.
255   format(
256       "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
257       "  ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n");
258   format("  if (message_arena == nullptr) {\n");
259   if (IsCrossFileMessage(descriptor_)) {
260     format(
261         "    delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n");
262   } else {
263     format("    delete $field$;\n");
264   }
265   format(
266       "  }\n"
267       "  if ($name$) {\n");
268   if (IsCrossFileMessage(descriptor_)) {
269     // We have to read the arena through the virtual method, because the type
270     // isn't defined in this file.
271     format(
272         "    ::$proto_ns$::Arena* submessage_arena =\n"
273         "        ::$proto_ns$::Arena::InternalGetOwningArena(\n"
274         "                reinterpret_cast<::$proto_ns$::MessageLite*>("
275         "$name$));\n");
276   } else {
277     format(
278         "    ::$proto_ns$::Arena* submessage_arena =\n"
279         "        ::$proto_ns$::Arena::InternalGetOwningArena("
280         "$name$);\n");
281   }
282   format(
283       "    if (message_arena != submessage_arena) {\n"
284       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
285       "          message_arena, $name$, submessage_arena);\n"
286       "    }\n"
287       "    $set_hasbit$\n"
288       "  } else {\n"
289       "    $clear_hasbit$\n"
290       "  }\n");
291   if (implicit_weak_field_) {
292     format("  $field$ = reinterpret_cast<MessageLite*>($name$);\n");
293   } else {
294     format("  $field$ = $name$;\n");
295   }
296   format(
297       "$annotate_set$"
298       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
299       "}\n");
300 }
301 
GenerateInternalAccessorDeclarations(io::Printer * printer) const302 void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
303     io::Printer* printer) const {
304   Formatter format(printer, variables_);
305   if (implicit_weak_field_) {
306     format(
307         "static const ::$proto_ns$::MessageLite& $name$("
308         "const $classname$* msg);\n"
309         "static ::$proto_ns$::MessageLite* mutable_$name$("
310         "$classname$* msg);\n");
311   } else {
312     format("static const $type$& $name$(const $classname$* msg);\n");
313   }
314 }
315 
GenerateInternalAccessorDefinitions(io::Printer * printer) const316 void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
317     io::Printer* printer) const {
318   // In theory, these accessors could be inline in _Internal. However, in
319   // practice, the linker is then not able to throw them out making implicit
320   // weak dependencies not work at all.
321   Formatter format(printer, variables_);
322   if (implicit_weak_field_) {
323     // These private accessors are used by MergeFrom and
324     // MergePartialFromCodedStream, and their purpose is to provide access to
325     // the field without creating a strong dependency on the message type.
326     format(
327         "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
328         "    const $classname$* msg) {\n"
329         "  if (msg->$field$ != nullptr) {\n"
330         "    return *msg->$field$;\n"
331         "  } else {\n"
332         "    return *$type_default_instance_ptr$;\n"
333         "  }\n"
334         "}\n");
335     format(
336         "::$proto_ns$::MessageLite*\n"
337         "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
338     if (HasHasbit(descriptor_)) {
339       format("  msg->$set_hasbit$\n");
340     }
341     if (descriptor_->real_containing_oneof() == nullptr) {
342       format("  if (msg->$field$ == nullptr) {\n");
343     } else {
344       format(
345           "  if (!msg->_internal_has_$name$()) {\n"
346           "    msg->clear_$oneof_name$();\n"
347           "    msg->set_has_$name$();\n");
348     }
349     format(
350         "    msg->$field$ = $type_default_instance_ptr$->New(\n"
351         "        msg->GetArenaForAllocation());\n"
352         "  }\n"
353         "  return msg->$field$;\n"
354         "}\n");
355   } else {
356     // This inline accessor directly returns member field and is used in
357     // Serialize such that AFDO profile correctly captures access information to
358     // message fields under serialize.
359     format(
360         "const $type$&\n"
361         "$classname$::_Internal::$name$(const $classname$* msg) {\n"
362         "  return *msg->$field$;\n"
363         "}\n");
364   }
365 }
366 
GenerateClearingCode(io::Printer * printer) const367 void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
368   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
369 
370   Formatter format(printer, variables_);
371   if (!HasHasbit(descriptor_)) {
372     // If we don't have has-bits, message presence is indicated only by ptr !=
373     // nullptr. Thus on clear, we need to delete the object.
374     format(
375         "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n"
376         "  delete $field$;\n"
377         "}\n"
378         "$field$ = nullptr;\n");
379   } else {
380     format("if ($field$ != nullptr) $field$->Clear();\n");
381   }
382 }
383 
GenerateMessageClearingCode(io::Printer * printer) const384 void MessageFieldGenerator::GenerateMessageClearingCode(
385     io::Printer* printer) const {
386   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
387 
388   Formatter format(printer, variables_);
389   if (!HasHasbit(descriptor_)) {
390     // If we don't have has-bits, message presence is indicated only by ptr !=
391     // nullptr. Thus on clear, we need to delete the object.
392     format(
393         "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n"
394         "  delete $field$;\n"
395         "}\n"
396         "$field$ = nullptr;\n");
397   } else {
398     format(
399         "$DCHK$($field$ != nullptr);\n"
400         "$field$->Clear();\n");
401   }
402 }
403 
GenerateMergingCode(io::Printer * printer) const404 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
405   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
406 
407   Formatter format(printer, variables_);
408   if (implicit_weak_field_) {
409     format(
410         "_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
411         "    _Internal::$name$(&from));\n");
412   } else {
413     format(
414         "_internal_mutable_$name$()->$type$::MergeFrom(from._internal_$name$())"
415         ";\n");
416   }
417 }
418 
GenerateSwappingCode(io::Printer * printer) const419 void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
420   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
421 
422   Formatter format(printer, variables_);
423   format("swap($field$, other->$field$);\n");
424 }
425 
GenerateDestructorCode(io::Printer * printer) const426 void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
427   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
428 
429   Formatter format(printer, variables_);
430   if (options_.opensource_runtime) {
431     // TODO(gerbens) Remove this when we don't need to destruct default
432     // instances.  In google3 a default instance will never get deleted so we
433     // don't need to worry about that but in opensource protobuf default
434     // instances are deleted in shutdown process and we need to take special
435     // care when handling them.
436     format("if (this != internal_default_instance()) ");
437   }
438   format("delete $field$;\n");
439 }
440 
GenerateConstructorCode(io::Printer * printer) const441 void MessageFieldGenerator::GenerateConstructorCode(
442     io::Printer* printer) const {
443   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
444 
445   Formatter format(printer, variables_);
446   format("$field$ = nullptr;\n");
447 }
448 
GenerateCopyConstructorCode(io::Printer * printer) const449 void MessageFieldGenerator::GenerateCopyConstructorCode(
450     io::Printer* printer) const {
451   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
452 
453   Formatter format(printer, variables_);
454   format(
455       "if (from._internal_has_$name$()) {\n"
456       "  $field$ = new $type$(*from.$field$);\n"
457       "} else {\n"
458       "  $field$ = nullptr;\n"
459       "}\n");
460 }
461 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const462 void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
463     io::Printer* printer) const {
464   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
465 
466   Formatter format(printer, variables_);
467   if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
468     format(
469         "target = ::$proto_ns$::internal::WireFormatLite::\n"
470         "  InternalWrite$declared_type$($number$, _Internal::$name$(this),\n"
471         "    _Internal::$name$(this).GetCachedSize(), target, stream);\n");
472   } else {
473     format(
474         "target = stream->EnsureSpace(target);\n"
475         "target = ::$proto_ns$::internal::WireFormatLite::\n"
476         "  InternalWrite$declared_type$(\n"
477         "    $number$, _Internal::$name$(this), target, stream);\n");
478   }
479 }
480 
GenerateByteSize(io::Printer * printer) const481 void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
482   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
483 
484   Formatter format(printer, variables_);
485   format(
486       "total_size += $tag_size$ +\n"
487       "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
488       "    *$field$);\n");
489 }
490 
GenerateIsInitialized(io::Printer * printer) const491 void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
492   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
493 
494   if (!has_required_fields_) return;
495 
496   Formatter format(printer, variables_);
497   format(
498       "if (_internal_has_$name$()) {\n"
499       "  if (!$field$->IsInitialized()) return false;\n"
500       "}\n");
501 }
502 
GenerateConstinitInitializer(io::Printer * printer) const503 void MessageFieldGenerator::GenerateConstinitInitializer(
504     io::Printer* printer) const {
505   Formatter format(printer, variables_);
506   format("$name$_(nullptr)");
507 }
508 
509 // ===================================================================
510 
MessageOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)511 MessageOneofFieldGenerator::MessageOneofFieldGenerator(
512     const FieldDescriptor* descriptor, const Options& options,
513     MessageSCCAnalyzer* scc_analyzer)
514     : MessageFieldGenerator(descriptor, options, scc_analyzer) {
515   SetCommonOneofFieldVariables(descriptor, &variables_);
516 }
517 
~MessageOneofFieldGenerator()518 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
519 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const520 void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
521     io::Printer* printer) const {
522   Formatter format(printer, variables_);
523   format(
524       "void $classname$::set_allocated_$name$($type$* $name$) {\n"
525       "  ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"
526       "  clear_$oneof_name$();\n"
527       "  if ($name$) {\n");
528   if (descriptor_->file() != descriptor_->message_type()->file()) {
529     // We have to read the arena through the virtual method, because the type
530     // isn't defined in this file.
531     format(
532         "    ::$proto_ns$::Arena* submessage_arena =\n"
533         "        ::$proto_ns$::Arena::InternalGetOwningArena(\n"
534         "                reinterpret_cast<::$proto_ns$::MessageLite*>("
535         "$name$));\n");
536   } else {
537     format(
538         "    ::$proto_ns$::Arena* submessage_arena =\n"
539         "      ::$proto_ns$::Arena::InternalGetOwningArena($name$);\n");
540   }
541   format(
542       "    if (message_arena != submessage_arena) {\n"
543       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
544       "          message_arena, $name$, submessage_arena);\n"
545       "    }\n"
546       "    set_has_$name$();\n"
547       "    $field$ = $name$;\n"
548       "  }\n"
549       "$annotate_set$"
550       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
551       "}\n");
552 }
553 
GenerateInlineAccessorDefinitions(io::Printer * printer) const554 void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
555     io::Printer* printer) const {
556   Formatter format(printer, variables_);
557   format(
558       "inline $type$* $classname$::$release_name$() {\n"
559       "$annotate_release$"
560       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
561       "$type_reference_function$"
562       "  if (_internal_has_$name$()) {\n"
563       "    clear_has_$oneof_name$();\n"
564       "    $type$* temp = $casted_member$;\n"
565       "    if (GetArenaForAllocation() != nullptr) {\n"
566       "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
567       "    }\n"
568       "    $field$ = nullptr;\n"
569       "    return temp;\n"
570       "  } else {\n"
571       "    return nullptr;\n"
572       "  }\n"
573       "}\n");
574 
575   format(
576       "inline const $type$& $classname$::_internal_$name$() const {\n"
577       "$type_reference_function$"
578       "  return _internal_has_$name$()\n"
579       "      ? $casted_member_const$\n"
580       "      : reinterpret_cast< $type$&>($type_default_instance$);\n"
581       "}\n"
582       "inline const $type$& $classname$::$name$() const {\n"
583       "$annotate_get$"
584       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
585       "  return _internal_$name$();\n"
586       "}\n"
587       "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
588       "$annotate_release$"
589       "  // @@protoc_insertion_point(field_unsafe_arena_release"
590       ":$full_name$)\n"
591       "$type_reference_function$"
592       "  if (_internal_has_$name$()) {\n"
593       "    clear_has_$oneof_name$();\n"
594       "    $type$* temp = $casted_member$;\n"
595       "    $field$ = nullptr;\n"
596       "    return temp;\n"
597       "  } else {\n"
598       "    return nullptr;\n"
599       "  }\n"
600       "}\n"
601       "inline void $classname$::unsafe_arena_set_allocated_$name$"
602       "($type$* $name$) {\n"
603       // We rely on the oneof clear method to free the earlier contents of
604       // this oneof. We can directly use the pointer we're given to set the
605       // new value.
606       "  clear_$oneof_name$();\n"
607       "  if ($name$) {\n"
608       "    set_has_$name$();\n");
609   if (implicit_weak_field_) {
610     format(
611         "    $field$ = "
612         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
613   } else {
614     format("    $field$ = $name$;\n");
615   }
616   format(
617       "  }\n"
618       "$annotate_set$"
619       "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
620       "$full_name$)\n"
621       "}\n"
622       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
623       "$type_reference_function$"
624       "  if (!_internal_has_$name$()) {\n"
625       "    clear_$oneof_name$();\n"
626       "    set_has_$name$();\n");
627   if (implicit_weak_field_) {
628     format(
629         "    $field$ = "
630         "reinterpret_cast<::$proto_ns$::MessageLite*>(CreateMaybeMessage< "
631         "$type$ >(GetArenaForAllocation()));\n");
632   } else {
633     format(
634         "    $field$ = CreateMaybeMessage< $type$ "
635         ">(GetArenaForAllocation());\n");
636   }
637   format(
638       "  }\n"
639       "  return $casted_member$;\n"
640       "}\n"
641       "inline $type$* $classname$::mutable_$name$() {\n"
642       "  $type$* _msg = _internal_mutable_$name$();\n"
643       "$annotate_mutable$"
644       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
645       "  return _msg;\n"
646       "}\n");
647 }
648 
GenerateClearingCode(io::Printer * printer) const649 void MessageOneofFieldGenerator::GenerateClearingCode(
650     io::Printer* printer) const {
651   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
652 
653   Formatter format(printer, variables_);
654   format(
655       "if (GetArenaForAllocation() == nullptr) {\n"
656       "  delete $field$;\n"
657       "}\n");
658 }
659 
GenerateMessageClearingCode(io::Printer * printer) const660 void MessageOneofFieldGenerator::GenerateMessageClearingCode(
661     io::Printer* printer) const {
662   GenerateClearingCode(printer);
663 }
664 
GenerateSwappingCode(io::Printer * printer) const665 void MessageOneofFieldGenerator::GenerateSwappingCode(
666     io::Printer* printer) const {
667   // Don't print any swapping code. Swapping the union will swap this field.
668 }
669 
GenerateDestructorCode(io::Printer * printer) const670 void MessageOneofFieldGenerator::GenerateDestructorCode(
671     io::Printer* printer) const {
672   // We inherit from MessageFieldGenerator, so we need to override the default
673   // behavior.
674 }
675 
GenerateConstructorCode(io::Printer * printer) const676 void MessageOneofFieldGenerator::GenerateConstructorCode(
677     io::Printer* printer) const {
678   // Don't print any constructor code. The field is in a union. We allocate
679   // space only when this field is used.
680 }
681 
GenerateIsInitialized(io::Printer * printer) const682 void MessageOneofFieldGenerator::GenerateIsInitialized(
683     io::Printer* printer) const {
684   if (!has_required_fields_) return;
685 
686   Formatter format(printer, variables_);
687   format(
688       "if (_internal_has_$name$()) {\n"
689       "  if (!$field$->IsInitialized()) return false;\n"
690       "}\n");
691 }
692 
693 // ===================================================================
694 
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)695 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
696     const FieldDescriptor* descriptor, const Options& options,
697     MessageSCCAnalyzer* scc_analyzer)
698     : FieldGenerator(descriptor, options),
699       implicit_weak_field_(
700           IsImplicitWeakField(descriptor, options, scc_analyzer)),
701       has_required_fields_(
702           scc_analyzer->HasRequiredFields(descriptor->message_type())) {
703   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
704 }
705 
~RepeatedMessageFieldGenerator()706 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
707 
GeneratePrivateMembers(io::Printer * printer) const708 void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
709     io::Printer* printer) const {
710   Formatter format(printer, variables_);
711   if (implicit_weak_field_) {
712     format("::$proto_ns$::WeakRepeatedPtrField< $type$ > $name$_;\n");
713   } else {
714     format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
715   }
716 }
717 
GenerateAccessorDeclarations(io::Printer * printer) const718 void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
719     io::Printer* printer) const {
720   Formatter format(printer, variables_);
721   if (IsFieldStripped(descriptor_, options_)) {
722     format(
723         "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
724         "__builtin_trap(); }\n"
725         "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
726         "    ${1$mutable_$name$$}$() { __builtin_trap(); }\n"
727         "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { "
728         "__builtin_trap(); }\n"
729         "$deprecated_attr$$type$* ${1$add_$name$$}$() { "
730         "__builtin_trap(); }\n"
731         "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
732         "    ${1$$name$$}$() const { __builtin_trap(); }\n",
733         descriptor_);
734     return;
735   }
736   format(
737       "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
738       "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
739       "    ${1$mutable_$name$$}$();\n",
740       descriptor_);
741   if (!IsFieldStripped(descriptor_, options_)) {
742     format(
743         "private:\n"
744         "const $type$& ${1$_internal_$name$$}$(int index) const;\n"
745         "$type$* ${1$_internal_add_$name$$}$();\n"
746         "public:\n",
747         descriptor_);
748   }
749   format(
750       "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
751       "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
752       "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
753       "    ${1$$name$$}$() const;\n",
754       descriptor_);
755 }
756 
GenerateInlineAccessorDefinitions(io::Printer * printer) const757 void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
758     io::Printer* printer) const {
759   Formatter format(printer, variables_);
760   format.Set("weak", implicit_weak_field_ ? ".weak" : "");
761 
762   format(
763       "inline $type$* $classname$::mutable_$name$(int index) {\n"
764       "$annotate_mutable$"
765       // TODO(dlj): move insertion points
766       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
767       "$type_reference_function$"
768       "  return $field$$weak$.Mutable(index);\n"
769       "}\n"
770       "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
771       "$classname$::mutable_$name$() {\n"
772       "$annotate_mutable_list$"
773       "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
774       "$type_reference_function$"
775       "  return &$field$$weak$;\n"
776       "}\n");
777 
778   if (options_.safe_boundary_check) {
779     format(
780         "inline const $type$& $classname$::_internal_$name$(int index) const "
781         "{\n"
782         "  return $field$$weak$.InternalCheckedGet(index,\n"
783         "      reinterpret_cast<const $type$&>($type_default_instance$));\n"
784         "}\n");
785   } else {
786     format(
787         "inline const $type$& $classname$::_internal_$name$(int index) const "
788         "{\n"
789         "$type_reference_function$"
790         "  return $field$$weak$.Get(index);\n"
791         "}\n");
792   }
793 
794   format(
795       "inline const $type$& $classname$::$name$(int index) const {\n"
796       "$annotate_get$"
797       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
798       "  return _internal_$name$(index);\n"
799       "}\n"
800       "inline $type$* $classname$::_internal_add_$name$() {\n"
801       "  return $field$$weak$.Add();\n"
802       "}\n"
803       "inline $type$* $classname$::add_$name$() {\n"
804       "  $type$* _add = _internal_add_$name$();\n"
805       "$annotate_add_mutable$"
806       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
807       "  return _add;\n"
808       "}\n");
809 
810   format(
811       "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
812       "$classname$::$name$() const {\n"
813       "$annotate_list$"
814       "  // @@protoc_insertion_point(field_list:$full_name$)\n"
815       "$type_reference_function$"
816       "  return $field$$weak$;\n"
817       "}\n");
818 }
819 
GenerateClearingCode(io::Printer * printer) const820 void RepeatedMessageFieldGenerator::GenerateClearingCode(
821     io::Printer* printer) const {
822   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
823 
824   Formatter format(printer, variables_);
825   format("$field$.Clear();\n");
826 }
827 
GenerateMergingCode(io::Printer * printer) const828 void RepeatedMessageFieldGenerator::GenerateMergingCode(
829     io::Printer* printer) const {
830   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
831 
832   Formatter format(printer, variables_);
833   format("$field$.MergeFrom(from.$field$);\n");
834 }
835 
GenerateSwappingCode(io::Printer * printer) const836 void RepeatedMessageFieldGenerator::GenerateSwappingCode(
837     io::Printer* printer) const {
838   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
839 
840   Formatter format(printer, variables_);
841   format("$field$.InternalSwap(&other->$field$);\n");
842 }
843 
GenerateConstructorCode(io::Printer * printer) const844 void RepeatedMessageFieldGenerator::GenerateConstructorCode(
845     io::Printer* printer) const {
846   // Not needed for repeated fields.
847 }
848 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const849 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
850     io::Printer* printer) const {
851   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
852 
853   Formatter format(printer, variables_);
854   if (implicit_weak_field_) {
855     format(
856         "for (auto it = this->$field$.pointer_begin(),\n"
857         "          end = this->$field$.pointer_end(); it < end; ++it) {\n");
858     if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
859       format(
860           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
861           "    InternalWrite$declared_type$($number$, "
862           "**it, (**it).GetCachedSize(), target, stream);\n");
863     } else {
864       format(
865           "  target = stream->EnsureSpace(target);\n"
866           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
867           "    InternalWrite$declared_type$($number$, **it, target, "
868           "stream);\n");
869     }
870     format("}\n");
871   } else {
872     format(
873         "for (unsigned i = 0,\n"
874         "    n = static_cast<unsigned>(this->_internal_$name$_size());"
875         " i < n; i++) {\n");
876     if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
877       format(
878           "  const auto& repfield = this->_internal_$name$(i);\n"
879           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
880           "      InternalWrite$declared_type$($number$, "
881           "repfield, repfield.GetCachedSize(), target, stream);\n"
882           "}\n");
883     } else {
884       format(
885           "  target = stream->EnsureSpace(target);\n"
886           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
887           "    InternalWrite$declared_type$($number$, "
888           "this->_internal_$name$(i), target, stream);\n"
889           "}\n");
890     }
891   }
892 }
893 
GenerateByteSize(io::Printer * printer) const894 void RepeatedMessageFieldGenerator::GenerateByteSize(
895     io::Printer* printer) const {
896   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
897 
898   Formatter format(printer, variables_);
899   format(
900       "total_size += $tag_size$UL * this->_internal_$name$_size();\n"
901       "for (const auto& msg : this->$field$) {\n"
902       "  total_size +=\n"
903       "    ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
904       "}\n");
905 }
906 
GenerateIsInitialized(io::Printer * printer) const907 void RepeatedMessageFieldGenerator::GenerateIsInitialized(
908     io::Printer* printer) const {
909   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
910 
911   if (!has_required_fields_) return;
912 
913   Formatter format(printer, variables_);
914   if (implicit_weak_field_) {
915     format(
916         "if (!::$proto_ns$::internal::AllAreInitializedWeak($field$.weak))\n"
917         "  return false;\n");
918   } else {
919     format(
920         "if (!::$proto_ns$::internal::AllAreInitialized($field$))\n"
921         "  return false;\n");
922   }
923 }
924 
GenerateConstinitInitializer(io::Printer * printer) const925 void RepeatedMessageFieldGenerator::GenerateConstinitInitializer(
926     io::Printer* printer) const {
927   Formatter format(printer, variables_);
928   format("$name$_()");
929 }
930 
931 }  // namespace cpp
932 }  // namespace compiler
933 }  // namespace protobuf
934 }  // namespace google
935