• 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 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(" +
71                        (*variables)["type_default_instance"] + ");\n")
72                     : "";
73   // NOTE: Escaped here to unblock proto1->proto2 migration.
74   // TODO(liujisi): Extend this to apply for other conflicting methods.
75   (*variables)["release_name"] =
76       SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
77   (*variables)["full_name"] = descriptor->full_name();
78 }
79 
80 }  // namespace
81 
82 // ===================================================================
83 
MessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)84 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
85                                              const Options& options,
86                                              MessageSCCAnalyzer* scc_analyzer)
87     : FieldGenerator(descriptor, options),
88       implicit_weak_field_(
89           IsImplicitWeakField(descriptor, options, scc_analyzer)) {
90   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
91 }
92 
~MessageFieldGenerator()93 MessageFieldGenerator::~MessageFieldGenerator() {}
94 
GeneratePrivateMembers(io::Printer * printer) const95 void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
96   Formatter format(printer, variables_);
97   if (implicit_weak_field_) {
98     format("::$proto_ns$::MessageLite* $name$_;\n");
99   } else {
100     format("$type$* $name$_;\n");
101   }
102 }
103 
GenerateAccessorDeclarations(io::Printer * printer) const104 void MessageFieldGenerator::GenerateAccessorDeclarations(
105     io::Printer* printer) const {
106   Formatter format(printer, variables_);
107   if (!IsFieldUsed(descriptor_, options_)) {
108     format(
109         "$deprecated_attr$const $type$& ${1$$name$$}$() const { "
110         "__builtin_trap(); }\n"
111         "$deprecated_attr$$type$* ${1$$release_name$$}$() { "
112         "__builtin_trap(); }\n"
113         "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
114         "__builtin_trap(); }\n"
115         "$deprecated_attr$void ${1$set_allocated_$name$$}$"
116         "($type$* $name$) { __builtin_trap(); }\n",
117         descriptor_);
118     if (SupportsArenas(descriptor_)) {
119       format(
120           "$deprecated_attr$void "
121           "${1$unsafe_arena_set_allocated_$name$$}$(\n"
122           "    $type$* $name$) { __builtin_trap(); }\n"
123           "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
124           "__builtin_trap(); }\n",
125           descriptor_);
126     }
127     return;
128   }
129   format(
130       "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
131       "$deprecated_attr$$type$* ${1$$release_name$$}$();\n"
132       "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
133       "$deprecated_attr$void ${1$set_allocated_$name$$}$"
134       "($type$* $name$);\n",
135       descriptor_);
136   if (IsFieldUsed(descriptor_, options_)) {
137     format(
138         "private:\n"
139         "const $type$& ${1$_internal_$name$$}$() const;\n"
140         "$type$* ${1$_internal_mutable_$name$$}$();\n"
141         "public:\n",
142         descriptor_);
143   }
144   if (SupportsArenas(descriptor_)) {
145     format(
146         "$deprecated_attr$void "
147         "${1$unsafe_arena_set_allocated_$name$$}$(\n"
148         "    $type$* $name$);\n"
149         "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
150         descriptor_);
151   }
152 }
153 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const154 void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
155     io::Printer* printer) const {
156 }
157 
GenerateInlineAccessorDefinitions(io::Printer * printer) const158 void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
159     io::Printer* printer) const {
160   Formatter format(printer, variables_);
161   format(
162       "inline const $type$& $classname$::_internal_$name$() const {\n"
163       "$type_reference_function$"
164       "  const $type$* p = $casted_member$;\n"
165       "  return p != nullptr ? *p : *reinterpret_cast<const $type$*>(\n"
166       "      &$type_default_instance$);\n"
167       "}\n"
168       "inline const $type$& $classname$::$name$() const {\n"
169       "$annotate_accessor$"
170       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
171       "  return _internal_$name$();\n"
172       "}\n");
173 
174   if (SupportsArenas(descriptor_)) {
175     format(
176         "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
177         "    $type$* $name$) {\n"
178         "$annotate_accessor$"
179         // If we're not on an arena, free whatever we were holding before.
180         // (If we are on arena, we can just forget the earlier pointer.)
181         "  if (GetArena() == nullptr) {\n"
182         "    delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
183         "  }\n");
184     if (implicit_weak_field_) {
185       format(
186           "  $name$_ = "
187           "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
188     } else {
189       format("  $name$_ = $name$;\n");
190     }
191     format(
192         "  if ($name$) {\n"
193         "    $set_hasbit$\n"
194         "  } else {\n"
195         "    $clear_hasbit$\n"
196         "  }\n"
197         "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
198         ":$full_name$)\n"
199         "}\n");
200     format(
201         "inline $type$* $classname$::$release_name$() {\n"
202         "$type_reference_function$"
203         "  $clear_hasbit$\n"
204         "  $type$* temp = $casted_member$;\n"
205         "  $name$_ = nullptr;\n"
206         "  if (GetArena() != nullptr) {\n"
207         "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
208         "  }\n"
209         "  return temp;\n"
210         "}\n"
211         "inline $type$* $classname$::unsafe_arena_release_$name$() {\n");
212   } else {
213     format("inline $type$* $classname$::$release_name$() {\n");
214   }
215   format(
216       "$annotate_accessor$"
217       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
218       "$type_reference_function$"
219       "  $clear_hasbit$\n"
220       "  $type$* temp = $casted_member$;\n"
221       "  $name$_ = nullptr;\n"
222       "  return temp;\n"
223       "}\n");
224 
225   format(
226       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
227       "$type_reference_function$"
228       "  $set_hasbit$\n"
229       "  if ($name$_ == nullptr) {\n"
230       "    auto* p = CreateMaybeMessage<$type$>(GetArena());\n");
231   if (implicit_weak_field_) {
232     format("    $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
233   } else {
234     format("    $name$_ = p;\n");
235   }
236   format(
237       "  }\n"
238       "  return $casted_member$;\n"
239       "}\n"
240       "inline $type$* $classname$::mutable_$name$() {\n"
241       "$annotate_accessor$"
242       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
243       "  return _internal_mutable_$name$();\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       "$annotate_accessor$"
251       "  ::$proto_ns$::Arena* message_arena = GetArena();\n");
252   format("  if (message_arena == nullptr) {\n");
253   if (IsCrossFileMessage(descriptor_)) {
254     format(
255         "    delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
256   } else {
257     format("    delete $name$_;\n");
258   }
259   format(
260       "  }\n"
261       "  if ($name$) {\n");
262   if (SupportsArenas(descriptor_->message_type()) &&
263       IsCrossFileMessage(descriptor_)) {
264     // We have to read the arena through the virtual method, because the type
265     // isn't defined in this file.
266     format(
267         "    ::$proto_ns$::Arena* submessage_arena =\n"
268         "      "
269         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
270   } else if (!SupportsArenas(descriptor_->message_type())) {
271     format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
272   } else {
273     format(
274         "    ::$proto_ns$::Arena* submessage_arena =\n"
275         "      ::$proto_ns$::Arena::GetArena($name$);\n");
276   }
277   format(
278       "    if (message_arena != submessage_arena) {\n"
279       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
280       "          message_arena, $name$, submessage_arena);\n"
281       "    }\n"
282       "    $set_hasbit$\n"
283       "  } else {\n"
284       "    $clear_hasbit$\n"
285       "  }\n");
286   if (implicit_weak_field_) {
287     format("  $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
288   } else {
289     format("  $name$_ = $name$;\n");
290   }
291   format(
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     if (SupportsArenas(descriptor_)) {
334       format(
335           "::$proto_ns$::MessageLite*\n"
336           "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
337       if (HasFieldPresence(descriptor_->file())) {
338         format("  msg->$set_hasbit$\n");
339       }
340       format(
341           "  if (msg->$name$_ == nullptr) {\n"
342           "    if ($type_default_instance_ptr$ == nullptr) {\n"
343           "      msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
344           "          ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
345           "              msg->GetArena());\n"
346           "    } else {\n"
347           "      msg->$name$_ = reinterpret_cast<const "
348           "::$proto_ns$::MessageLite*>(\n"
349           "          $type_default_instance_ptr$)->New(msg->GetArena());\n"
350           "    }\n"
351           "  }\n"
352           "  return msg->$name$_;\n"
353           "}\n");
354     } else {
355       format(
356           "::$proto_ns$::MessageLite*\n"
357           "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
358       if (HasFieldPresence(descriptor_->file())) {
359         format("  msg->$set_hasbit$\n");
360       }
361       format(
362           "  if (msg->$name$_ == nullptr) {\n"
363           "    if ($type_default_instance_ptr$ == nullptr) {\n"
364           "      msg->$name$_ = "
365           "new ::$proto_ns$::internal::ImplicitWeakMessage;\n"
366           "    } else {\n"
367           "      msg->$name$_ = "
368           "reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
369           "          $type_default_instance_ptr$)->New();\n"
370           "    }\n"
371           "  }\n"
372           "  return msg->$name$_;\n"
373           "}\n");
374     }
375   } else {
376     // This inline accessor directly returns member field and is used in
377     // Serialize such that AFDO profile correctly captures access information to
378     // message fields under serialize.
379     format(
380         "const $type$&\n"
381         "$classname$::_Internal::$name$(const $classname$* msg) {\n"
382         "  return *msg->$field_member$;\n"
383         "}\n");
384   }
385 }
386 
GenerateClearingCode(io::Printer * printer) const387 void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
388   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
389 
390   Formatter format(printer, variables_);
391   if (!HasFieldPresence(descriptor_->file())) {
392     // If we don't have has-bits, message presence is indicated only by ptr !=
393     // NULL. Thus on clear, we need to delete the object.
394     format(
395         "if (GetArena() == nullptr && $name$_ != nullptr) {\n"
396         "  delete $name$_;\n"
397         "}\n"
398         "$name$_ = nullptr;\n");
399   } else {
400     format("if ($name$_ != nullptr) $name$_->Clear();\n");
401   }
402 }
403 
GenerateMessageClearingCode(io::Printer * printer) const404 void MessageFieldGenerator::GenerateMessageClearingCode(
405     io::Printer* printer) const {
406   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
407 
408   Formatter format(printer, variables_);
409   if (!HasFieldPresence(descriptor_->file())) {
410     // If we don't have has-bits, message presence is indicated only by ptr !=
411     // NULL. Thus on clear, we need to delete the object.
412     format(
413         "if (GetArena() == nullptr && $name$_ != nullptr) {\n"
414         "  delete $name$_;\n"
415         "}\n"
416         "$name$_ = nullptr;\n");
417   } else {
418     format(
419         "$DCHK$($name$_ != nullptr);\n"
420         "$name$_->Clear();\n");
421   }
422 }
423 
GenerateMergingCode(io::Printer * printer) const424 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
425   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
426 
427   Formatter format(printer, variables_);
428   if (implicit_weak_field_) {
429     format(
430         "_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
431         "    _Internal::$name$(&from));\n");
432   } else {
433     format(
434         "_internal_mutable_$name$()->$type$::MergeFrom(from._internal_$name$())"
435         ";\n");
436   }
437 }
438 
GenerateSwappingCode(io::Printer * printer) const439 void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
440   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
441 
442   Formatter format(printer, variables_);
443   format("swap($name$_, other->$name$_);\n");
444 }
445 
GenerateDestructorCode(io::Printer * printer) const446 void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
447   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
448 
449   Formatter format(printer, variables_);
450   if (options_.opensource_runtime) {
451     // TODO(gerbens) Remove this when we don't need to destruct default
452     // instances.  In google3 a default instance will never get deleted so we
453     // don't need to worry about that but in opensource protobuf default
454     // instances are deleted in shutdown process and we need to take special
455     // care when handling them.
456     format("if (this != internal_default_instance()) ");
457   }
458   format("delete $name$_;\n");
459 }
460 
GenerateConstructorCode(io::Printer * printer) const461 void MessageFieldGenerator::GenerateConstructorCode(
462     io::Printer* printer) const {
463   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
464 
465   Formatter format(printer, variables_);
466   format("$name$_ = nullptr;\n");
467 }
468 
GenerateCopyConstructorCode(io::Printer * printer) const469 void MessageFieldGenerator::GenerateCopyConstructorCode(
470     io::Printer* printer) const {
471   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
472 
473   Formatter format(printer, variables_);
474   format(
475       "if (from._internal_has_$name$()) {\n"
476       "  $name$_ = new $type$(*from.$name$_);\n"
477       "} else {\n"
478       "  $name$_ = nullptr;\n"
479       "}\n");
480 }
481 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const482 void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
483     io::Printer* printer) const {
484   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
485 
486   Formatter format(printer, variables_);
487   format(
488       "target = stream->EnsureSpace(target);\n"
489       "target = ::$proto_ns$::internal::WireFormatLite::\n"
490       "  InternalWrite$declared_type$(\n"
491       "    $number$, _Internal::$name$(this), target, stream);\n");
492 }
493 
GenerateByteSize(io::Printer * printer) const494 void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
495   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
496 
497   Formatter format(printer, variables_);
498   format(
499       "total_size += $tag_size$ +\n"
500       "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
501       "    *$field_member$);\n");
502 }
503 
504 // ===================================================================
505 
MessageOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)506 MessageOneofFieldGenerator::MessageOneofFieldGenerator(
507     const FieldDescriptor* descriptor, const Options& options,
508     MessageSCCAnalyzer* scc_analyzer)
509     : MessageFieldGenerator(descriptor, options, scc_analyzer) {
510   SetCommonOneofFieldVariables(descriptor, &variables_);
511 }
512 
~MessageOneofFieldGenerator()513 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
514 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const515 void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
516     io::Printer* printer) const {
517   Formatter format(printer, variables_);
518   format(
519       "void $classname$::set_allocated_$name$($type$* $name$) {\n"
520       "$annotate_accessor$"
521       "  ::$proto_ns$::Arena* message_arena = GetArena();\n"
522       "  clear_$oneof_name$();\n"
523       "  if ($name$) {\n");
524   if (SupportsArenas(descriptor_->message_type()) &&
525       descriptor_->file() != descriptor_->message_type()->file()) {
526     // We have to read the arena through the virtual method, because the type
527     // isn't defined in this file.
528     format(
529         "    ::$proto_ns$::Arena* submessage_arena =\n"
530         "      "
531         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
532   } else if (!SupportsArenas(descriptor_->message_type())) {
533     format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
534   } else {
535     format(
536         "    ::$proto_ns$::Arena* submessage_arena =\n"
537         "      ::$proto_ns$::Arena::GetArena($name$);\n");
538   }
539   format(
540       "    if (message_arena != submessage_arena) {\n"
541       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
542       "          message_arena, $name$, submessage_arena);\n"
543       "    }\n"
544       "    set_has_$name$();\n"
545       "    $field_member$ = $name$;\n"
546       "  }\n"
547       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
548       "}\n");
549 }
550 
GenerateInlineAccessorDefinitions(io::Printer * printer) const551 void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
552     io::Printer* printer) const {
553   Formatter format(printer, variables_);
554   format(
555       "inline $type$* $classname$::$release_name$() {\n"
556       "$annotate_accessor$"
557       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
558       "  if (_internal_has_$name$()) {\n"
559       "    clear_has_$oneof_name$();\n"
560       "      $type$* temp = $field_member$;\n");
561   if (SupportsArenas(descriptor_)) {
562     format(
563         "    if (GetArena() != nullptr) {\n"
564         "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
565         "    }\n");
566   }
567   format(
568       "    $field_member$ = 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       "  return _internal_has_$name$()\n"
578       "      ? *$field_member$\n"
579       "      : *reinterpret_cast< $type$*>(&$type_default_instance$);\n"
580       "}\n"
581       "inline const $type$& $classname$::$name$() const {\n"
582       "$annotate_accessor$"
583       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
584       "  return _internal_$name$();\n"
585       "}\n");
586 
587   if (SupportsArenas(descriptor_)) {
588     format(
589         "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
590         "$annotate_accessor$"
591         "  // @@protoc_insertion_point(field_unsafe_arena_release"
592         ":$full_name$)\n"
593         "  if (_internal_has_$name$()) {\n"
594         "    clear_has_$oneof_name$();\n"
595         "    $type$* temp = $field_member$;\n"
596         "    $field_member$ = nullptr;\n"
597         "    return temp;\n"
598         "  } else {\n"
599         "    return nullptr;\n"
600         "  }\n"
601         "}\n"
602         "inline void $classname$::unsafe_arena_set_allocated_$name$"
603         "($type$* $name$) {\n"
604         "$annotate_accessor$"
605         // We rely on the oneof clear method to free the earlier contents of
606         // this oneof. We can directly use the pointer we're given to set the
607         // new value.
608         "  clear_$oneof_name$();\n"
609         "  if ($name$) {\n"
610         "    set_has_$name$();\n"
611         "    $field_member$ = $name$;\n"
612         "  }\n"
613         "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
614         "$full_name$)\n"
615         "}\n");
616   }
617 
618   format(
619       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
620       "  if (!_internal_has_$name$()) {\n"
621       "    clear_$oneof_name$();\n"
622       "    set_has_$name$();\n"
623       "    $field_member$ = CreateMaybeMessage< $type$ >(GetArena());\n"
624       "  }\n"
625       "  return $field_member$;\n"
626       "}\n"
627       "inline $type$* $classname$::mutable_$name$() {\n"
628       "$annotate_accessor$"
629       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
630       "  return _internal_mutable_$name$();\n"
631       "}\n");
632 }
633 
GenerateClearingCode(io::Printer * printer) const634 void MessageOneofFieldGenerator::GenerateClearingCode(
635     io::Printer* printer) const {
636   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
637 
638   Formatter format(printer, variables_);
639   if (SupportsArenas(descriptor_)) {
640     format(
641         "if (GetArena() == nullptr) {\n"
642         "  delete $field_member$;\n"
643         "}\n");
644   } else {
645     format("delete $field_member$;\n");
646   }
647 }
648 
GenerateMessageClearingCode(io::Printer * printer) const649 void MessageOneofFieldGenerator::GenerateMessageClearingCode(
650     io::Printer* printer) const {
651   GenerateClearingCode(printer);
652 }
653 
GenerateSwappingCode(io::Printer * printer) const654 void MessageOneofFieldGenerator::GenerateSwappingCode(
655     io::Printer* printer) const {
656   // Don't print any swapping code. Swapping the union will swap this field.
657 }
658 
GenerateDestructorCode(io::Printer * printer) const659 void MessageOneofFieldGenerator::GenerateDestructorCode(
660     io::Printer* printer) const {
661   // We inherit from MessageFieldGenerator, so we need to override the default
662   // behavior.
663 }
664 
GenerateConstructorCode(io::Printer * printer) const665 void MessageOneofFieldGenerator::GenerateConstructorCode(
666     io::Printer* printer) const {
667   // Don't print any constructor code. The field is in a union. We allocate
668   // space only when this field is used.
669 }
670 
671 // ===================================================================
672 
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)673 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
674     const FieldDescriptor* descriptor, const Options& options,
675     MessageSCCAnalyzer* scc_analyzer)
676     : FieldGenerator(descriptor, options),
677       implicit_weak_field_(
678           IsImplicitWeakField(descriptor, options, scc_analyzer)) {
679   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
680 }
681 
~RepeatedMessageFieldGenerator()682 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
683 
GeneratePrivateMembers(io::Printer * printer) const684 void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
685     io::Printer* printer) const {
686   Formatter format(printer, variables_);
687   if (implicit_weak_field_) {
688     format("::$proto_ns$::WeakRepeatedPtrField< $type$ > $name$_;\n");
689   } else {
690     format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
691   }
692 }
693 
GenerateAccessorDeclarations(io::Printer * printer) const694 void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
695     io::Printer* printer) const {
696   Formatter format(printer, variables_);
697   if (!IsFieldUsed(descriptor_, options_)) {
698     format(
699         "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
700         "__builtin_trap(); }\n"
701         "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
702         "    ${1$mutable_$name$$}$() { __builtin_trap(); }\n"
703         "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { "
704         "__builtin_trap(); }\n"
705         "$deprecated_attr$$type$* ${1$add_$name$$}$() { "
706         "__builtin_trap(); }\n"
707         "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
708         "    ${1$$name$$}$() const { __builtin_trap(); }\n",
709         descriptor_);
710     return;
711   }
712   format(
713       "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
714       "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
715       "    ${1$mutable_$name$$}$();\n",
716       descriptor_);
717   if (IsFieldUsed(descriptor_, options_)) {
718     format(
719         "private:\n"
720         "const $type$& ${1$_internal_$name$$}$(int index) const;\n"
721         "$type$* ${1$_internal_add_$name$$}$();\n"
722         "public:\n",
723         descriptor_);
724   }
725   format(
726       "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
727       "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
728       "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
729       "    ${1$$name$$}$() const;\n",
730       descriptor_);
731 }
732 
GenerateInlineAccessorDefinitions(io::Printer * printer) const733 void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
734     io::Printer* printer) const {
735   Formatter format(printer, variables_);
736   format.Set("weak", implicit_weak_field_ ? ".weak" : "");
737 
738   format(
739       "inline $type$* $classname$::mutable_$name$(int index) {\n"
740       "$annotate_accessor$"
741       // TODO(dlj): move insertion points
742       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
743       "$type_reference_function$"
744       "  return $name$_$weak$.Mutable(index);\n"
745       "}\n"
746       "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
747       "$classname$::mutable_$name$() {\n"
748       "$annotate_accessor$"
749       "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
750       "$type_reference_function$"
751       "  return &$name$_$weak$;\n"
752       "}\n");
753 
754   if (options_.safe_boundary_check) {
755     format(
756         "inline const $type$& $classname$::_internal_$name$(int index) const "
757         "{\n"
758         "  return $name$_$weak$.InternalCheckedGet(index,\n"
759         "      *reinterpret_cast<const $type$*>(&$type_default_instance$));\n"
760         "}\n");
761   } else {
762     format(
763         "inline const $type$& $classname$::_internal_$name$(int index) const "
764         "{\n"
765         "$type_reference_function$"
766         "  return $name$_$weak$.Get(index);\n"
767         "}\n");
768   }
769 
770   format(
771       "inline const $type$& $classname$::$name$(int index) const {\n"
772       "$annotate_accessor$"
773       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
774       "  return _internal_$name$(index);\n"
775       "}\n"
776       "inline $type$* $classname$::_internal_add_$name$() {\n"
777       "  return $name$_$weak$.Add();\n"
778       "}\n"
779       "inline $type$* $classname$::add_$name$() {\n"
780       "$annotate_accessor$"
781       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
782       "  return _internal_add_$name$();\n"
783       "}\n");
784 
785   format(
786       "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
787       "$classname$::$name$() const {\n"
788       "$annotate_accessor$"
789       "  // @@protoc_insertion_point(field_list:$full_name$)\n"
790       "$type_reference_function$"
791       "  return $name$_$weak$;\n"
792       "}\n");
793 }
794 
GenerateClearingCode(io::Printer * printer) const795 void RepeatedMessageFieldGenerator::GenerateClearingCode(
796     io::Printer* printer) const {
797   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
798 
799   Formatter format(printer, variables_);
800   format("$name$_.Clear();\n");
801 }
802 
GenerateMergingCode(io::Printer * printer) const803 void RepeatedMessageFieldGenerator::GenerateMergingCode(
804     io::Printer* printer) const {
805   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
806 
807   Formatter format(printer, variables_);
808   format("$name$_.MergeFrom(from.$name$_);\n");
809 }
810 
GenerateSwappingCode(io::Printer * printer) const811 void RepeatedMessageFieldGenerator::GenerateSwappingCode(
812     io::Printer* printer) const {
813   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
814 
815   Formatter format(printer, variables_);
816   format("$name$_.InternalSwap(&other->$name$_);\n");
817 }
818 
GenerateConstructorCode(io::Printer * printer) const819 void RepeatedMessageFieldGenerator::GenerateConstructorCode(
820     io::Printer* printer) const {
821   // Not needed for repeated fields.
822 }
823 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const824 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
825     io::Printer* printer) const {
826   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
827 
828   Formatter format(printer, variables_);
829   if (implicit_weak_field_) {
830     format(
831         "for (auto it = this->$name$_.pointer_begin(),\n"
832         "          end = this->$name$_.pointer_end(); it < end; ++it) {\n"
833         "  target = stream->EnsureSpace(target);\n"
834         "  target = ::$proto_ns$::internal::WireFormatLite::\n"
835         "    InternalWrite$declared_type$($number$, **it, target, stream);\n"
836         "}\n");
837   } else {
838     format(
839         "for (unsigned int i = 0,\n"
840         "    n = static_cast<unsigned int>(this->_internal_$name$_size()); i < "
841         "n; i++) "
842         "{\n"
843         "  target = stream->EnsureSpace(target);\n"
844         "  target = ::$proto_ns$::internal::WireFormatLite::\n"
845         "    InternalWrite$declared_type$($number$, "
846         "this->_internal_$name$(i), target, stream);\n"
847         "}\n");
848   }
849 }
850 
GenerateByteSize(io::Printer * printer) const851 void RepeatedMessageFieldGenerator::GenerateByteSize(
852     io::Printer* printer) const {
853   GOOGLE_CHECK(IsFieldUsed(descriptor_, options_));
854 
855   Formatter format(printer, variables_);
856   format(
857       "total_size += $tag_size$UL * this->_internal_$name$_size();\n"
858       "for (const auto& msg : this->$name$_) {\n"
859       "  total_size +=\n"
860       "    ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
861       "}\n");
862 }
863 
864 }  // namespace cpp
865 }  // namespace compiler
866 }  // namespace protobuf
867 }  // namespace google
868