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