• 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 #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 string & type,const string & expression,bool implicit_weak_field)47 string ReinterpretCast(const string& type, const string& expression,
48                        bool implicit_weak_field) {
49   if (implicit_weak_field) {
50     return "reinterpret_cast< " + type + " >(" + expression + ")";
51   } else {
52     return expression;
53   }
54 }
55 
SetMessageVariables(const FieldDescriptor * descriptor,const Options & options,bool implicit_weak,std::map<std::string,std::string> * variables)56 void SetMessageVariables(const FieldDescriptor* descriptor,
57                          const Options& options, bool implicit_weak,
58                          std::map<std::string, std::string>* variables) {
59   SetCommonFieldVariables(descriptor, variables, options);
60   (*variables)["type"] = FieldMessageTypeName(descriptor, options);
61   (*variables)["casted_member"] = ReinterpretCast(
62       (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak);
63   (*variables)["type_default_instance"] =
64       QualifiedDefaultInstanceName(descriptor->message_type(), options);
65   (*variables)["type_reference_function"] =
66       implicit_weak
67           ? ("  " + ReferenceFunctionName(descriptor->message_type(), options) +
68              "();\n")
69           : "";
70   (*variables)["stream_writer"] =
71       (*variables)["declared_type"] +
72       (HasFastArraySerialization(descriptor->message_type()->file(), options)
73            ? "MaybeToArray"
74            : "");
75   // NOTE: Escaped here to unblock proto1->proto2 migration.
76   // TODO(liujisi): Extend this to apply for other conflicting methods.
77   (*variables)["release_name"] =
78       SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
79   (*variables)["full_name"] = descriptor->full_name();
80 }
81 
82 }  // namespace
83 
84 // ===================================================================
85 
MessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)86 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
87                                              const Options& options,
88                                              MessageSCCAnalyzer* scc_analyzer)
89     : FieldGenerator(descriptor, options),
90       implicit_weak_field_(
91           IsImplicitWeakField(descriptor, options, scc_analyzer)) {
92   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
93 }
94 
~MessageFieldGenerator()95 MessageFieldGenerator::~MessageFieldGenerator() {}
96 
GeneratePrivateMembers(io::Printer * printer) const97 void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
98   Formatter format(printer, variables_);
99   if (implicit_weak_field_) {
100     format("::$proto_ns$::MessageLite* $name$_;\n");
101   } else {
102     format("$type$* $name$_;\n");
103   }
104 }
105 
GenerateAccessorDeclarations(io::Printer * printer) const106 void MessageFieldGenerator::GenerateAccessorDeclarations(
107     io::Printer* printer) const {
108   Formatter format(printer, variables_);
109   format(
110       "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
111       "$deprecated_attr$$type$* ${1$$release_name$$}$();\n"
112       "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
113       "$deprecated_attr$void ${1$set_allocated_$name$$}$"
114       "($type$* $name$);\n",
115       descriptor_);
116   if (SupportsArenas(descriptor_)) {
117     format(
118         "$deprecated_attr$void "
119         "${1$unsafe_arena_set_allocated_$name$$}$(\n"
120         "    $type$* $name$);\n"
121         "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
122         descriptor_);
123   }
124 }
125 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const126 void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
127     io::Printer* printer) const {
128   Formatter format(printer, variables_);
129   if (SupportsArenas(descriptor_)) {
130     format(
131         "void $classname$::unsafe_arena_set_allocated_$name$(\n"
132         "    $type$* $name$) {\n"
133         // If we're not on an arena, free whatever we were holding before.
134         // (If we are on arena, we can just forget the earlier pointer.)
135         "  if (GetArenaNoVirtual() == nullptr) {\n"
136         "    delete $name$_;\n"
137         "  }\n"
138         "  $name$_ = $name$;\n"
139         "  if ($name$) {\n"
140         "    $set_hasbit$\n"
141         "  } else {\n"
142         "    $clear_hasbit$\n"
143         "  }\n"
144         "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
145         ":$full_name$)\n"
146         "}\n");
147   }
148 }
149 
GenerateInlineAccessorDefinitions(io::Printer * printer) const150 void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
151     io::Printer* printer) const {
152   Formatter format(printer, variables_);
153   format(
154       "inline const $type$& $classname$::$name$() const {\n"
155       "  const $type$* p = $casted_member$;\n"
156       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
157       "  return p != nullptr ? *p : *reinterpret_cast<const $type$*>(\n"
158       "      &$type_default_instance$);\n"
159       "}\n");
160 
161   format(
162       "inline $type$* $classname$::$release_name$() {\n"
163       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
164       "$type_reference_function$"
165       "  $clear_hasbit$\n"
166       "  $type$* temp = $casted_member$;\n");
167   if (SupportsArenas(descriptor_)) {
168     format(
169         "  if (GetArenaNoVirtual() != nullptr) {\n"
170         "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
171         "  }\n");
172   }
173   format(
174       "  $name$_ = nullptr;\n"
175       "  return temp;\n"
176       "}\n");
177 
178   if (SupportsArenas(descriptor_)) {
179     format(
180         "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
181         "  // "
182         "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
183         "$type_reference_function$"
184         "  $clear_hasbit$\n"
185         "  $type$* temp = $casted_member$;\n"
186         "  $name$_ = nullptr;\n"
187         "  return temp;\n"
188         "}\n");
189   }
190 
191   format(
192       "inline $type$* $classname$::mutable_$name$() {\n"
193       "  $set_hasbit$\n"
194       "  if ($name$_ == nullptr) {\n"
195       "    auto* p = CreateMaybeMessage<$type$>(GetArenaNoVirtual());\n");
196   if (implicit_weak_field_) {
197     format("    $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
198   } else {
199     format("    $name$_ = p;\n");
200   }
201   format(
202       "  }\n"
203       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
204       "  return $casted_member$;\n"
205       "}\n");
206 
207   // We handle the most common case inline, and delegate less common cases to
208   // the slow fallback function.
209   format(
210       "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
211       "  ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n");
212   format("  if (message_arena == nullptr) {\n");
213   if (IsCrossFileMessage(descriptor_)) {
214     format(
215         "    delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
216   } else {
217     format("    delete $name$_;\n");
218   }
219   format(
220       "  }\n"
221       "  if ($name$) {\n");
222   if (SupportsArenas(descriptor_->message_type()) &&
223       IsCrossFileMessage(descriptor_)) {
224     // We have to read the arena through the virtual method, because the type
225     // isn't defined in this file.
226     format(
227         "    ::$proto_ns$::Arena* submessage_arena =\n"
228         "      "
229         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
230   } else if (!SupportsArenas(descriptor_->message_type())) {
231     format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
232   } else {
233     format(
234         "    ::$proto_ns$::Arena* submessage_arena =\n"
235         "      ::$proto_ns$::Arena::GetArena($name$);\n");
236   }
237   format(
238       "    if (message_arena != submessage_arena) {\n"
239       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
240       "          message_arena, $name$, submessage_arena);\n"
241       "    }\n"
242       "    $set_hasbit$\n"
243       "  } else {\n"
244       "    $clear_hasbit$\n"
245       "  }\n");
246   if (implicit_weak_field_) {
247     format("  $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
248   } else {
249     format("  $name$_ = $name$;\n");
250   }
251   format(
252       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
253       "}\n");
254 }
255 
GenerateInternalAccessorDeclarations(io::Printer * printer) const256 void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
257     io::Printer* printer) const {
258   Formatter format(printer, variables_);
259   if (implicit_weak_field_) {
260     format(
261         "static const ::$proto_ns$::MessageLite& $name$("
262         "const $classname$* msg);\n"
263         "static ::$proto_ns$::MessageLite* mutable_$name$("
264         "$classname$* msg);\n");
265   } else {
266     format("static const $type$& $name$(const $classname$* msg);\n");
267   }
268 }
269 
GenerateInternalAccessorDefinitions(io::Printer * printer) const270 void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
271     io::Printer* printer) const {
272   // In theory, these accessors could be inline in _Internal. However, in
273   // practice, the linker is then not able to throw them out making implicit
274   // weak dependencies not work at all.
275   Formatter format(printer, variables_);
276   if (implicit_weak_field_) {
277     // These private accessors are used by MergeFrom and
278     // MergePartialFromCodedStream, and their purpose is to provide access to
279     // the field without creating a strong dependency on the message type.
280     format(
281         "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
282         "    const $classname$* msg) {\n"
283         "  if (msg->$name$_ != nullptr) {\n"
284         "    return *msg->$name$_;\n"
285         "  } else if (&$type_default_instance$ != nullptr) {\n"
286         "    return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
287         "        &$type_default_instance$);\n"
288         "  } else {\n"
289         "    return "
290         "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
291         "  }\n"
292         "}\n");
293     if (SupportsArenas(descriptor_)) {
294       format(
295           "::$proto_ns$::MessageLite*\n"
296           "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
297       if (HasFieldPresence(descriptor_->file())) {
298         format("  msg->$set_hasbit$\n");
299       }
300       format(
301           "  if (msg->$name$_ == nullptr) {\n"
302           "    if (&$type_default_instance$ == nullptr) {\n"
303           "      msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
304           "          ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
305           "              msg->GetArenaNoVirtual());\n"
306           "    } else {\n"
307           "      msg->$name$_ = reinterpret_cast<const "
308           "::$proto_ns$::MessageLite*>(\n"
309           "          &$type_default_instance$)->New("
310           "msg->GetArenaNoVirtual());\n"
311           "    }\n"
312           "  }\n"
313           "  return msg->$name$_;\n"
314           "}\n");
315     } else {
316       format(
317           "::$proto_ns$::MessageLite*\n"
318           "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
319       if (HasFieldPresence(descriptor_->file())) {
320         format("  msg->$set_hasbit$\n");
321       }
322       format(
323           "  if (msg->$name$_ == nullptr) {\n"
324           "    if (&$type_default_instance$ == nullptr) {\n"
325           "      msg->$name$_ = "
326           "new ::$proto_ns$::internal::ImplicitWeakMessage;\n"
327           "    } else {\n"
328           "      msg->$name$_ = "
329           "reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
330           "          &$type_default_instance$)->New();\n"
331           "    }\n"
332           "  }\n"
333           "  return msg->$name$_;\n"
334           "}\n");
335     }
336   } else {
337     // This inline accessor directly returns member field and is used in
338     // Serialize such that AFDO profile correctly captures access information to
339     // message fields under serialize.
340     format(
341         "const $type$&\n"
342         "$classname$::_Internal::$name$(const $classname$* msg) {\n"
343         "  return *msg->$field_member$;\n"
344         "}\n");
345   }
346 }
347 
GenerateClearingCode(io::Printer * printer) const348 void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
349   Formatter format(printer, variables_);
350   if (!HasFieldPresence(descriptor_->file())) {
351     // If we don't have has-bits, message presence is indicated only by ptr !=
352     // NULL. Thus on clear, we need to delete the object.
353     format(
354         "if (GetArenaNoVirtual() == nullptr && $name$_ != nullptr) {\n"
355         "  delete $name$_;\n"
356         "}\n"
357         "$name$_ = nullptr;\n");
358   } else {
359     format("if ($name$_ != nullptr) $name$_->Clear();\n");
360   }
361 }
362 
GenerateMessageClearingCode(io::Printer * printer) const363 void MessageFieldGenerator::GenerateMessageClearingCode(
364     io::Printer* printer) const {
365   Formatter format(printer, variables_);
366   if (!HasFieldPresence(descriptor_->file())) {
367     // If we don't have has-bits, message presence is indicated only by ptr !=
368     // NULL. Thus on clear, we need to delete the object.
369     format(
370         "if (GetArenaNoVirtual() == nullptr && $name$_ != nullptr) {\n"
371         "  delete $name$_;\n"
372         "}\n"
373         "$name$_ = nullptr;\n");
374   } else {
375     format(
376         "$DCHK$($name$_ != nullptr);\n"
377         "$name$_->Clear();\n");
378   }
379 }
380 
GenerateMergingCode(io::Printer * printer) const381 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
382   Formatter format(printer, variables_);
383   if (implicit_weak_field_) {
384     format(
385         "_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
386         "    _Internal::$name$(&from));\n");
387   } else {
388     format("mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
389   }
390 }
391 
GenerateSwappingCode(io::Printer * printer) const392 void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
393   Formatter format(printer, variables_);
394   format("swap($name$_, other->$name$_);\n");
395 }
396 
GenerateDestructorCode(io::Printer * printer) const397 void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
398   Formatter format(printer, variables_);
399   if (options_.opensource_runtime) {
400     // TODO(gerbens) Remove this when we don't need to destruct default
401     // instances.  In google3 a default instance will never get deleted so we
402     // don't need to worry about that but in opensource protobuf default
403     // instances are deleted in shutdown process and we need to take special
404     // care when handling them.
405     format("if (this != internal_default_instance()) ");
406   }
407   format("delete $name$_;\n");
408 }
409 
GenerateConstructorCode(io::Printer * printer) const410 void MessageFieldGenerator::GenerateConstructorCode(
411     io::Printer* printer) const {
412   Formatter format(printer, variables_);
413   format("$name$_ = nullptr;\n");
414 }
415 
GenerateCopyConstructorCode(io::Printer * printer) const416 void MessageFieldGenerator::GenerateCopyConstructorCode(
417     io::Printer* printer) const {
418   Formatter format(printer, variables_);
419   format(
420       "if (from.has_$name$()) {\n"
421       "  $name$_ = new $type$(*from.$name$_);\n"
422       "} else {\n"
423       "  $name$_ = nullptr;\n"
424       "}\n");
425 }
426 
GenerateMergeFromCodedStream(io::Printer * printer) const427 void MessageFieldGenerator::GenerateMergeFromCodedStream(
428     io::Printer* printer) const {
429   Formatter format(printer, variables_);
430   if (implicit_weak_field_) {
431     format(
432         "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessage(\n"
433         "     input, _Internal::mutable_$name$(this)));\n");
434   } else if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
435     format(
436         "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessage(\n"
437         "     input, mutable_$name$()));\n");
438   } else {
439     format(
440         "DO_(::$proto_ns$::internal::WireFormatLite::ReadGroup(\n"
441         "      $number$, input, mutable_$name$()));\n");
442   }
443 }
444 
GenerateSerializeWithCachedSizes(io::Printer * printer) const445 void MessageFieldGenerator::GenerateSerializeWithCachedSizes(
446     io::Printer* printer) const {
447   Formatter format(printer, variables_);
448   format(
449       "::$proto_ns$::internal::WireFormatLite::Write$stream_writer$(\n"
450       "  $number$, _Internal::$name$(this), output);\n");
451 }
452 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const453 void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
454     io::Printer* printer) const {
455   Formatter format(printer, variables_);
456   format(
457       "target = ::$proto_ns$::internal::WireFormatLite::\n"
458       "  InternalWrite$declared_type$ToArray(\n"
459       "    $number$, _Internal::$name$(this), target);\n");
460 }
461 
GenerateByteSize(io::Printer * printer) const462 void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
463   Formatter format(printer, variables_);
464   format(
465       "total_size += $tag_size$ +\n"
466       "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
467       "    *$field_member$);\n");
468 }
469 
470 // ===================================================================
471 
MessageOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)472 MessageOneofFieldGenerator::MessageOneofFieldGenerator(
473     const FieldDescriptor* descriptor, const Options& options,
474     MessageSCCAnalyzer* scc_analyzer)
475     : MessageFieldGenerator(descriptor, options, scc_analyzer) {
476   SetCommonOneofFieldVariables(descriptor, &variables_);
477 }
478 
~MessageOneofFieldGenerator()479 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
480 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const481 void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
482     io::Printer* printer) const {
483   Formatter format(printer, variables_);
484   format(
485       "void $classname$::set_allocated_$name$($type$* $name$) {\n"
486       "  ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n"
487       "  clear_$oneof_name$();\n"
488       "  if ($name$) {\n");
489   if (SupportsArenas(descriptor_->message_type()) &&
490       descriptor_->file() != descriptor_->message_type()->file()) {
491     // We have to read the arena through the virtual method, because the type
492     // isn't defined in this file.
493     format(
494         "    ::$proto_ns$::Arena* submessage_arena =\n"
495         "      "
496         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
497   } else if (!SupportsArenas(descriptor_->message_type())) {
498     format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
499   } else {
500     format(
501         "    ::$proto_ns$::Arena* submessage_arena =\n"
502         "      ::$proto_ns$::Arena::GetArena($name$);\n");
503   }
504   format(
505       "    if (message_arena != submessage_arena) {\n"
506       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
507       "          message_arena, $name$, submessage_arena);\n"
508       "    }\n"
509       "    set_has_$name$();\n"
510       "    $field_member$ = $name$;\n"
511       "  }\n"
512       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
513       "}\n");
514 }
515 
GenerateInlineAccessorDefinitions(io::Printer * printer) const516 void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
517     io::Printer* printer) const {
518   Formatter format(printer, variables_);
519   format(
520       "inline $type$* $classname$::$release_name$() {\n"
521       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
522       "  if (has_$name$()) {\n"
523       "    clear_has_$oneof_name$();\n"
524       "      $type$* temp = $field_member$;\n");
525   if (SupportsArenas(descriptor_)) {
526     format(
527         "    if (GetArenaNoVirtual() != nullptr) {\n"
528         "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
529         "    }\n");
530   }
531   format(
532       "    $field_member$ = nullptr;\n"
533       "    return temp;\n"
534       "  } else {\n"
535       "    return nullptr;\n"
536       "  }\n"
537       "}\n");
538 
539   format(
540       "inline const $type$& $classname$::$name$() const {\n"
541       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
542       "  return has_$name$()\n"
543       "      ? *$field_member$\n"
544       "      : *reinterpret_cast< $type$*>(&$type_default_instance$);\n"
545       "}\n");
546 
547   if (SupportsArenas(descriptor_)) {
548     format(
549         "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
550         "  // @@protoc_insertion_point(field_unsafe_arena_release"
551         ":$full_name$)\n"
552         "  if (has_$name$()) {\n"
553         "    clear_has_$oneof_name$();\n"
554         "    $type$* temp = $field_member$;\n"
555         "    $field_member$ = nullptr;\n"
556         "    return temp;\n"
557         "  } else {\n"
558         "    return nullptr;\n"
559         "  }\n"
560         "}\n"
561         "inline void $classname$::unsafe_arena_set_allocated_$name$"
562         "($type$* $name$) {\n"
563         // We rely on the oneof clear method to free the earlier contents of
564         // this oneof. We can directly use the pointer we're given to set the
565         // new value.
566         "  clear_$oneof_name$();\n"
567         "  if ($name$) {\n"
568         "    set_has_$name$();\n"
569         "    $field_member$ = $name$;\n"
570         "  }\n"
571         "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
572         "$full_name$)\n"
573         "}\n");
574   }
575 
576   format(
577       "inline $type$* $classname$::mutable_$name$() {\n"
578       "  if (!has_$name$()) {\n"
579       "    clear_$oneof_name$();\n"
580       "    set_has_$name$();\n"
581       "    $field_member$ = CreateMaybeMessage< $type$ >(\n"
582       "        GetArenaNoVirtual());\n"
583       "  }\n"
584       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
585       "  return $field_member$;\n"
586       "}\n");
587 }
588 
GenerateClearingCode(io::Printer * printer) const589 void MessageOneofFieldGenerator::GenerateClearingCode(
590     io::Printer* printer) const {
591   Formatter format(printer, variables_);
592   if (SupportsArenas(descriptor_)) {
593     format(
594         "if (GetArenaNoVirtual() == nullptr) {\n"
595         "  delete $field_member$;\n"
596         "}\n");
597   } else {
598     format("delete $field_member$;\n");
599   }
600 }
601 
GenerateMessageClearingCode(io::Printer * printer) const602 void MessageOneofFieldGenerator::GenerateMessageClearingCode(
603     io::Printer* printer) const {
604   GenerateClearingCode(printer);
605 }
606 
GenerateSwappingCode(io::Printer * printer) const607 void MessageOneofFieldGenerator::GenerateSwappingCode(
608     io::Printer* printer) const {
609   // Don't print any swapping code. Swapping the union will swap this field.
610 }
611 
GenerateDestructorCode(io::Printer * printer) const612 void MessageOneofFieldGenerator::GenerateDestructorCode(
613     io::Printer* printer) const {
614   // We inherit from MessageFieldGenerator, so we need to override the default
615   // behavior.
616 }
617 
GenerateConstructorCode(io::Printer * printer) const618 void MessageOneofFieldGenerator::GenerateConstructorCode(
619     io::Printer* printer) const {
620   // Don't print any constructor code. The field is in a union. We allocate
621   // space only when this field is used.
622 }
623 
624 // ===================================================================
625 
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)626 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
627     const FieldDescriptor* descriptor, const Options& options,
628     MessageSCCAnalyzer* scc_analyzer)
629     : FieldGenerator(descriptor, options),
630       implicit_weak_field_(
631           IsImplicitWeakField(descriptor, options, scc_analyzer)) {
632   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
633 }
634 
~RepeatedMessageFieldGenerator()635 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
636 
GeneratePrivateMembers(io::Printer * printer) const637 void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
638     io::Printer* printer) const {
639   Formatter format(printer, variables_);
640   format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
641 }
642 
GenerateAccessorDeclarations(io::Printer * printer) const643 void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
644     io::Printer* printer) const {
645   Formatter format(printer, variables_);
646   format(
647       "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
648       "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
649       "    ${1$mutable_$name$$}$();\n"
650       "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
651       "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
652       "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
653       "    ${1$$name$$}$() const;\n",
654       descriptor_);
655 }
656 
GenerateInlineAccessorDefinitions(io::Printer * printer) const657 void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
658     io::Printer* printer) const {
659   Formatter format(printer, variables_);
660   format(
661       "inline $type$* $classname$::mutable_$name$(int index) {\n"
662       // TODO(dlj): move insertion points
663       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
664       "$type_reference_function$"
665       "  return $name$_.Mutable(index);\n"
666       "}\n"
667       "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
668       "$classname$::mutable_$name$() {\n"
669       "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
670       "$type_reference_function$"
671       "  return &$name$_;\n"
672       "}\n");
673 
674   if (options_.safe_boundary_check) {
675     format(
676         "inline const $type$& $classname$::$name$(int index) const {\n"
677         "  // @@protoc_insertion_point(field_get:$full_name$)\n"
678         "  return $name$_.InternalCheckedGet(index,\n"
679         "      *reinterpret_cast<const $type$*>(&$type_default_instance$));\n"
680         "}\n");
681   } else {
682     format(
683         "inline const $type$& $classname$::$name$(int index) const {\n"
684         "  // @@protoc_insertion_point(field_get:$full_name$)\n"
685         "$type_reference_function$"
686         "  return $name$_.Get(index);\n"
687         "}\n");
688   }
689 
690   format(
691       "inline $type$* $classname$::add_$name$() {\n"
692       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
693       "  return $name$_.Add();\n"
694       "}\n");
695 
696   format(
697       "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
698       "$classname$::$name$() const {\n"
699       "  // @@protoc_insertion_point(field_list:$full_name$)\n"
700       "$type_reference_function$"
701       "  return $name$_;\n"
702       "}\n");
703 }
704 
GenerateClearingCode(io::Printer * printer) const705 void RepeatedMessageFieldGenerator::GenerateClearingCode(
706     io::Printer* printer) const {
707   Formatter format(printer, variables_);
708   if (implicit_weak_field_) {
709     format(
710         "CastToBase(&$name$_)->Clear<"
711         "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>();\n");
712   } else {
713     format("$name$_.Clear();\n");
714   }
715 }
716 
GenerateMergingCode(io::Printer * printer) const717 void RepeatedMessageFieldGenerator::GenerateMergingCode(
718     io::Printer* printer) const {
719   Formatter format(printer, variables_);
720   if (implicit_weak_field_) {
721     format(
722         "CastToBase(&$name$_)->MergeFrom<"
723         "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>(CastToBase("
724         "from.$name$_));\n");
725   } else {
726     format("$name$_.MergeFrom(from.$name$_);\n");
727   }
728 }
729 
GenerateSwappingCode(io::Printer * printer) const730 void RepeatedMessageFieldGenerator::GenerateSwappingCode(
731     io::Printer* printer) const {
732   Formatter format(printer, variables_);
733   format("CastToBase(&$name$_)->InternalSwap(CastToBase(&other->$name$_));\n");
734 }
735 
GenerateConstructorCode(io::Printer * printer) const736 void RepeatedMessageFieldGenerator::GenerateConstructorCode(
737     io::Printer* printer) const {
738   // Not needed for repeated fields.
739 }
740 
GenerateMergeFromCodedStream(io::Printer * printer) const741 void RepeatedMessageFieldGenerator::GenerateMergeFromCodedStream(
742     io::Printer* printer) const {
743   Formatter format(printer, variables_);
744   if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
745     if (implicit_weak_field_) {
746       format(
747           "DO_(::$proto_ns$::internal::WireFormatLite::"
748           "ReadMessage(input, CastToBase(&$name$_)->AddWeak(\n"
749           "    reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
750           "        &$type_default_instance$))));\n");
751     } else {
752       format(
753           "DO_(::$proto_ns$::internal::WireFormatLite::"
754           "ReadMessage(\n"
755           "      input, add_$name$()));\n");
756     }
757   } else {
758     format(
759         "DO_(::$proto_ns$::internal::WireFormatLite::"
760         "ReadGroup($number$, input, add_$name$()));\n");
761   }
762 }
763 
GenerateSerializeWithCachedSizes(io::Printer * printer) const764 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizes(
765     io::Printer* printer) const {
766   Formatter format(printer, variables_);
767   format(
768       "for (unsigned int i = 0,\n"
769       "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
770       "  ::$proto_ns$::internal::WireFormatLite::Write$stream_writer$(\n"
771       "    $number$,\n");
772   if (implicit_weak_field_) {
773     format(
774         "    CastToBase($name$_).Get<"
775         "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>("
776         "static_cast<int>(i)),\n");
777   } else {
778     format("    this->$name$(static_cast<int>(i)),\n");
779   }
780   format(
781       "    output);\n"
782       "}\n");
783 }
784 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const785 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
786     io::Printer* printer) const {
787   Formatter format(printer, variables_);
788   format(
789       "for (unsigned int i = 0,\n"
790       "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
791       "  target = ::$proto_ns$::internal::WireFormatLite::\n"
792       "    InternalWrite$declared_type$ToArray(\n"
793       "      $number$, this->$name$(static_cast<int>(i)), target);\n"
794       "}\n");
795 }
796 
GenerateByteSize(io::Printer * printer) const797 void RepeatedMessageFieldGenerator::GenerateByteSize(
798     io::Printer* printer) const {
799   Formatter format(printer, variables_);
800   format(
801       "{\n"
802       "  unsigned int count = static_cast<unsigned "
803       "int>(this->$name$_size());\n");
804   format.Indent();
805   format(
806       "total_size += $tag_size$UL * count;\n"
807       "for (unsigned int i = 0; i < count; i++) {\n"
808       "  total_size +=\n"
809       "    ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n");
810   if (implicit_weak_field_) {
811     format(
812         "      CastToBase($name$_).Get<"
813         "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>("
814         "static_cast<int>(i)));\n");
815   } else {
816     format("      this->$name$(static_cast<int>(i)));\n");
817   }
818   format("}\n");
819   format.Outdent();
820   format("}\n");
821 }
822 
823 }  // namespace cpp
824 }  // namespace compiler
825 }  // namespace protobuf
826 }  // namespace google
827