xref: /aosp_15_r20/external/cronet/third_party/protobuf/src/google/protobuf/compiler/cpp/message_field.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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: [email protected] (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   format(
195       "  if ($name$) {\n"
196       "    $set_hasbit$\n"
197       "  } else {\n"
198       "    $clear_hasbit$\n"
199       "  }\n"
200       "$annotate_set$"
201       "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
202       ":$full_name$)\n"
203       "}\n");
204   format(
205       "inline $type$* $classname$::$release_name$() {\n"
206       "$type_reference_function$"
207       "$annotate_release$"
208       "$maybe_prepare_split_message$"
209       "  $clear_hasbit$\n"
210       "  $type$* temp = $casted_member$;\n"
211       "  $field$ = nullptr;\n"
212       "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n"
213       "  auto* old =  reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n"
214       "  temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
215       "  if (GetArenaForAllocation() == nullptr) { delete old; }\n"
216       "#else  // PROTOBUF_FORCE_COPY_IN_RELEASE\n"
217       "  if (GetArenaForAllocation() != nullptr) {\n"
218       "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
219       "  }\n"
220       "#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE\n"
221       "  return temp;\n"
222       "}\n"
223       "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
224       "$annotate_release$"
225       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
226       "$type_reference_function$"
227       "$maybe_prepare_split_message$"
228       "  $clear_hasbit$\n"
229       "  $type$* temp = $casted_member$;\n"
230       "  $field$ = nullptr;\n"
231       "  return temp;\n"
232       "}\n");
233 
234   format(
235       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
236       "$type_reference_function$"
237       "  $set_hasbit$\n"
238       "  if ($field$ == nullptr) {\n"
239       "    auto* p = CreateMaybeMessage<$type$>(GetArenaForAllocation());\n");
240   if (implicit_weak_field_) {
241     format("    $field$ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
242   } else {
243     format("    $field$ = p;\n");
244   }
245   format(
246       "  }\n"
247       "  return $casted_member$;\n"
248       "}\n"
249       "inline $type$* $classname$::mutable_$name$() {\n"
250       // TODO(b/122856539): add tests to make sure all write accessors are able
251       // to prepare split message allocation.
252       "$maybe_prepare_split_message$"
253       "  $type$* _msg = _internal_mutable_$name$();\n"
254       "$annotate_mutable$"
255       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
256       "  return _msg;\n"
257       "}\n");
258 
259   // We handle the most common case inline, and delegate less common cases to
260   // the slow fallback function.
261   format(
262       "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
263       "  ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n");
264   format(
265       "$maybe_prepare_split_message$"
266       "  if (message_arena == nullptr) {\n");
267   if (IsCrossFileMessage(descriptor_)) {
268     format(
269         "    delete reinterpret_cast< ::$proto_ns$::MessageLite*>($field$);\n");
270   } else {
271     format("    delete $field$;\n");
272   }
273   format(
274       "  }\n"
275       "  if ($name$) {\n");
276   if (IsCrossFileMessage(descriptor_)) {
277     // We have to read the arena through the virtual method, because the type
278     // isn't defined in this file.
279     format(
280         "    ::$proto_ns$::Arena* submessage_arena =\n"
281         "        ::$proto_ns$::Arena::InternalGetOwningArena(\n"
282         "                reinterpret_cast<::$proto_ns$::MessageLite*>("
283         "$name$));\n");
284   } else {
285     format(
286         "    ::$proto_ns$::Arena* submessage_arena =\n"
287         "        ::$proto_ns$::Arena::InternalGetOwningArena("
288         "$name$);\n");
289   }
290   format(
291       "    if (message_arena != submessage_arena) {\n"
292       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
293       "          message_arena, $name$, submessage_arena);\n"
294       "    }\n"
295       "    $set_hasbit$\n"
296       "  } else {\n"
297       "    $clear_hasbit$\n"
298       "  }\n");
299   if (implicit_weak_field_) {
300     format("  $field$ = reinterpret_cast<MessageLite*>($name$);\n");
301   } else {
302     format("  $field$ = $name$;\n");
303   }
304   format(
305       "$annotate_set$"
306       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
307       "}\n");
308 }
309 
GenerateInternalAccessorDeclarations(io::Printer * printer) const310 void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
311     io::Printer* printer) const {
312   Formatter format(printer, variables_);
313   if (implicit_weak_field_) {
314     format(
315         "static const ::$proto_ns$::MessageLite& $name$("
316         "const $classname$* msg);\n"
317         "static ::$proto_ns$::MessageLite* mutable_$name$("
318         "$classname$* msg);\n");
319   } else {
320     format("static const $type$& $name$(const $classname$* msg);\n");
321   }
322 }
323 
GenerateInternalAccessorDefinitions(io::Printer * printer) const324 void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
325     io::Printer* printer) const {
326   // In theory, these accessors could be inline in _Internal. However, in
327   // practice, the linker is then not able to throw them out making implicit
328   // weak dependencies not work at all.
329   Formatter format(printer, variables_);
330   if (implicit_weak_field_) {
331     // These private accessors are used by MergeFrom and
332     // MergePartialFromCodedStream, and their purpose is to provide access to
333     // the field without creating a strong dependency on the message type.
334     format(
335         "const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
336         "    const $classname$* msg) {\n"
337         "  if (msg->$field$ != nullptr) {\n"
338         "    return *msg->$field$;\n"
339         "  } else {\n"
340         "    return *$type_default_instance_ptr$;\n"
341         "  }\n"
342         "}\n");
343     format(
344         "::$proto_ns$::MessageLite*\n"
345         "$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
346     if (HasHasbit(descriptor_)) {
347       format("  msg->$set_hasbit$\n");
348     }
349     if (descriptor_->real_containing_oneof() == nullptr) {
350       format("  if (msg->$field$ == nullptr) {\n");
351     } else {
352       format(
353           "  if (!msg->_internal_has_$name$()) {\n"
354           "    msg->clear_$oneof_name$();\n"
355           "    msg->set_has_$name$();\n");
356     }
357     format(
358         "    msg->$field$ = $type_default_instance_ptr$->New(\n"
359         "        msg->GetArenaForAllocation());\n"
360         "  }\n"
361         "  return msg->$field$;\n"
362         "}\n");
363   } else {
364     // This inline accessor directly returns member field and is used in
365     // Serialize such that AFDO profile correctly captures access information to
366     // message fields under serialize.
367     format(
368         "const $type$&\n"
369         "$classname$::_Internal::$name$(const $classname$* msg) {\n"
370         "  return *msg->$field$;\n"
371         "}\n");
372   }
373 }
374 
GenerateClearingCode(io::Printer * printer) const375 void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
376   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
377 
378   Formatter format(printer, variables_);
379   if (!HasHasbit(descriptor_)) {
380     // If we don't have has-bits, message presence is indicated only by ptr !=
381     // nullptr. Thus on clear, we need to delete the object.
382     format(
383         "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n"
384         "  delete $field$;\n"
385         "}\n"
386         "$field$ = nullptr;\n");
387   } else {
388     format("if ($field$ != nullptr) $field$->Clear();\n");
389   }
390 }
391 
GenerateMessageClearingCode(io::Printer * printer) const392 void MessageFieldGenerator::GenerateMessageClearingCode(
393     io::Printer* printer) const {
394   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
395 
396   Formatter format(printer, variables_);
397   if (!HasHasbit(descriptor_)) {
398     // If we don't have has-bits, message presence is indicated only by ptr !=
399     // nullptr. Thus on clear, we need to delete the object.
400     format(
401         "if (GetArenaForAllocation() == nullptr && $field$ != nullptr) {\n"
402         "  delete $field$;\n"
403         "}\n"
404         "$field$ = nullptr;\n");
405   } else {
406     format(
407         "$DCHK$($field$ != nullptr);\n"
408         "$field$->Clear();\n");
409   }
410 }
411 
GenerateMergingCode(io::Printer * printer) const412 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
413   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
414 
415   Formatter format(printer, variables_);
416   if (implicit_weak_field_) {
417     format(
418         "_Internal::mutable_$name$(_this)->CheckTypeAndMergeFrom(\n"
419         "    _Internal::$name$(&from));\n");
420   } else {
421     format(
422         "_this->_internal_mutable_$name$()->$type$::MergeFrom(\n"
423         "    from._internal_$name$());\n");
424   }
425 }
426 
GenerateSwappingCode(io::Printer * printer) const427 void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
428   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
429 
430   Formatter format(printer, variables_);
431   format("swap($field$, other->$field$);\n");
432 }
433 
GenerateDestructorCode(io::Printer * printer) const434 void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
435   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
436 
437   Formatter format(printer, variables_);
438   if (options_.opensource_runtime) {
439     // TODO(gerbens) Remove this when we don't need to destruct default
440     // instances.  In google3 a default instance will never get deleted so we
441     // don't need to worry about that but in opensource protobuf default
442     // instances are deleted in shutdown process and we need to take special
443     // care when handling them.
444     format("if (this != internal_default_instance()) ");
445   }
446   if (ShouldSplit(descriptor_, options_)) {
447     format("delete $cached_split_ptr$->$name$_;\n");
448     return;
449   }
450   format("delete $field$;\n");
451 }
452 
GenerateCopyConstructorCode(io::Printer * printer) const453 void MessageFieldGenerator::GenerateCopyConstructorCode(
454     io::Printer* printer) const {
455   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
456 
457   Formatter format(printer, variables_);
458   format(
459       "if (from._internal_has_$name$()) {\n"
460       "  _this->$field$ = new $type$(*from.$field$);\n"
461       "}\n");
462 }
463 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const464 void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
465     io::Printer* printer) const {
466   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
467 
468   Formatter format(printer, variables_);
469   if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
470     format(
471         "target = ::$proto_ns$::internal::WireFormatLite::\n"
472         "  InternalWrite$declared_type$($number$, _Internal::$name$(this),\n"
473         "    _Internal::$name$(this).GetCachedSize(), target, stream);\n");
474   } else {
475     format(
476         "target = stream->EnsureSpace(target);\n"
477         "target = ::$proto_ns$::internal::WireFormatLite::\n"
478         "  InternalWrite$declared_type$(\n"
479         "    $number$, _Internal::$name$(this), target, stream);\n");
480   }
481 }
482 
GenerateByteSize(io::Printer * printer) const483 void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
484   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
485 
486   Formatter format(printer, variables_);
487   format(
488       "total_size += $tag_size$ +\n"
489       "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
490       "    *$field$);\n");
491 }
492 
GenerateIsInitialized(io::Printer * printer) const493 void MessageFieldGenerator::GenerateIsInitialized(io::Printer* printer) const {
494   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
495 
496   if (!has_required_fields_) return;
497 
498   Formatter format(printer, variables_);
499   format(
500       "if (_internal_has_$name$()) {\n"
501       "  if (!$field$->IsInitialized()) return false;\n"
502       "}\n");
503 }
504 
GenerateConstexprAggregateInitializer(io::Printer * printer) const505 void MessageFieldGenerator::GenerateConstexprAggregateInitializer(
506     io::Printer* printer) const {
507   Formatter format(printer, variables_);
508   format("/*decltype($field$)*/nullptr");
509 }
510 
GenerateCopyAggregateInitializer(io::Printer * printer) const511 void MessageFieldGenerator::GenerateCopyAggregateInitializer(
512     io::Printer* printer) const {
513   Formatter format(printer, variables_);
514   format("decltype($field$){nullptr}");
515 }
516 
GenerateAggregateInitializer(io::Printer * printer) const517 void MessageFieldGenerator::GenerateAggregateInitializer(
518     io::Printer* printer) const {
519   Formatter format(printer, variables_);
520   if (ShouldSplit(descriptor_, options_)) {
521     format("decltype(Impl_::Split::$name$_){nullptr}");
522     return;
523   }
524   format("decltype($field$){nullptr}");
525 }
526 
527 // ===================================================================
528 
MessageOneofFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)529 MessageOneofFieldGenerator::MessageOneofFieldGenerator(
530     const FieldDescriptor* descriptor, const Options& options,
531     MessageSCCAnalyzer* scc_analyzer)
532     : MessageFieldGenerator(descriptor, options, scc_analyzer) {
533   SetCommonOneofFieldVariables(descriptor, &variables_);
534 }
535 
~MessageOneofFieldGenerator()536 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
537 
GenerateNonInlineAccessorDefinitions(io::Printer * printer) const538 void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
539     io::Printer* printer) const {
540   Formatter format(printer, variables_);
541   format(
542       "void $classname$::set_allocated_$name$($type$* $name$) {\n"
543       "  ::$proto_ns$::Arena* message_arena = GetArenaForAllocation();\n"
544       "  clear_$oneof_name$();\n"
545       "  if ($name$) {\n");
546   if (descriptor_->file() != descriptor_->message_type()->file()) {
547     // We have to read the arena through the virtual method, because the type
548     // isn't defined in this file.
549     format(
550         "    ::$proto_ns$::Arena* submessage_arena =\n"
551         "        ::$proto_ns$::Arena::InternalGetOwningArena(\n"
552         "                reinterpret_cast<::$proto_ns$::MessageLite*>("
553         "$name$));\n");
554   } else {
555     format(
556         "    ::$proto_ns$::Arena* submessage_arena =\n"
557         "      ::$proto_ns$::Arena::InternalGetOwningArena($name$);\n");
558   }
559   format(
560       "    if (message_arena != submessage_arena) {\n"
561       "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
562       "          message_arena, $name$, submessage_arena);\n"
563       "    }\n"
564       "    set_has_$name$();\n"
565       "    $field$ = $name$;\n"
566       "  }\n"
567       "$annotate_set$"
568       "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
569       "}\n");
570 }
571 
GenerateInlineAccessorDefinitions(io::Printer * printer) const572 void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
573     io::Printer* printer) const {
574   Formatter format(printer, variables_);
575   format(
576       "inline $type$* $classname$::$release_name$() {\n"
577       "$annotate_release$"
578       "  // @@protoc_insertion_point(field_release:$full_name$)\n"
579       "$type_reference_function$"
580       "  if (_internal_has_$name$()) {\n"
581       "    clear_has_$oneof_name$();\n"
582       "    $type$* temp = $casted_member$;\n"
583       "    if (GetArenaForAllocation() != nullptr) {\n"
584       "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
585       "    }\n"
586       "    $field$ = nullptr;\n"
587       "    return temp;\n"
588       "  } else {\n"
589       "    return nullptr;\n"
590       "  }\n"
591       "}\n");
592 
593   format(
594       "inline const $type$& $classname$::_internal_$name$() const {\n"
595       "$type_reference_function$"
596       "  return _internal_has_$name$()\n"
597       "      ? $casted_member_const$\n"
598       "      : reinterpret_cast< $type$&>($type_default_instance$);\n"
599       "}\n"
600       "inline const $type$& $classname$::$name$() const {\n"
601       "$annotate_get$"
602       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
603       "  return _internal_$name$();\n"
604       "}\n"
605       "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
606       "$annotate_release$"
607       "  // @@protoc_insertion_point(field_unsafe_arena_release"
608       ":$full_name$)\n"
609       "$type_reference_function$"
610       "  if (_internal_has_$name$()) {\n"
611       "    clear_has_$oneof_name$();\n"
612       "    $type$* temp = $casted_member$;\n"
613       "    $field$ = nullptr;\n"
614       "    return temp;\n"
615       "  } else {\n"
616       "    return nullptr;\n"
617       "  }\n"
618       "}\n"
619       "inline void $classname$::unsafe_arena_set_allocated_$name$"
620       "($type$* $name$) {\n"
621       // We rely on the oneof clear method to free the earlier contents of
622       // this oneof. We can directly use the pointer we're given to set the
623       // new value.
624       "  clear_$oneof_name$();\n"
625       "  if ($name$) {\n"
626       "    set_has_$name$();\n");
627   if (implicit_weak_field_) {
628     format(
629         "    $field$ = "
630         "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
631   } else {
632     format("    $field$ = $name$;\n");
633   }
634   format(
635       "  }\n"
636       "$annotate_set$"
637       "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
638       "$full_name$)\n"
639       "}\n"
640       "inline $type$* $classname$::_internal_mutable_$name$() {\n"
641       "$type_reference_function$"
642       "  if (!_internal_has_$name$()) {\n"
643       "    clear_$oneof_name$();\n"
644       "    set_has_$name$();\n");
645   if (implicit_weak_field_) {
646     format(
647         "    $field$ = "
648         "reinterpret_cast<::$proto_ns$::MessageLite*>(CreateMaybeMessage< "
649         "$type$ >(GetArenaForAllocation()));\n");
650   } else {
651     format(
652         "    $field$ = CreateMaybeMessage< $type$ "
653         ">(GetArenaForAllocation());\n");
654   }
655   format(
656       "  }\n"
657       "  return $casted_member$;\n"
658       "}\n"
659       "inline $type$* $classname$::mutable_$name$() {\n"
660       "  $type$* _msg = _internal_mutable_$name$();\n"
661       "$annotate_mutable$"
662       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
663       "  return _msg;\n"
664       "}\n");
665 }
666 
GenerateClearingCode(io::Printer * printer) const667 void MessageOneofFieldGenerator::GenerateClearingCode(
668     io::Printer* printer) const {
669   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
670 
671   Formatter format(printer, variables_);
672   format(
673       "if (GetArenaForAllocation() == nullptr) {\n"
674       "  delete $field$;\n"
675       "}\n");
676 }
677 
GenerateMessageClearingCode(io::Printer * printer) const678 void MessageOneofFieldGenerator::GenerateMessageClearingCode(
679     io::Printer* printer) const {
680   GenerateClearingCode(printer);
681 }
682 
GenerateSwappingCode(io::Printer * printer) const683 void MessageOneofFieldGenerator::GenerateSwappingCode(
684     io::Printer* printer) const {
685   // Don't print any swapping code. Swapping the union will swap this field.
686 }
687 
GenerateDestructorCode(io::Printer * printer) const688 void MessageOneofFieldGenerator::GenerateDestructorCode(
689     io::Printer* printer) const {
690   // We inherit from MessageFieldGenerator, so we need to override the default
691   // behavior.
692 }
693 
GenerateConstructorCode(io::Printer * printer) const694 void MessageOneofFieldGenerator::GenerateConstructorCode(
695     io::Printer* printer) const {
696   // Don't print any constructor code. The field is in a union. We allocate
697   // space only when this field is used.
698 }
699 
GenerateIsInitialized(io::Printer * printer) const700 void MessageOneofFieldGenerator::GenerateIsInitialized(
701     io::Printer* printer) const {
702   if (!has_required_fields_) return;
703 
704   Formatter format(printer, variables_);
705   format(
706       "if (_internal_has_$name$()) {\n"
707       "  if (!$field$->IsInitialized()) return false;\n"
708       "}\n");
709 }
710 
711 // ===================================================================
712 
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)713 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
714     const FieldDescriptor* descriptor, const Options& options,
715     MessageSCCAnalyzer* scc_analyzer)
716     : FieldGenerator(descriptor, options),
717       implicit_weak_field_(
718           IsImplicitWeakField(descriptor, options, scc_analyzer)),
719       has_required_fields_(
720           scc_analyzer->HasRequiredFields(descriptor->message_type())) {
721   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
722 }
723 
~RepeatedMessageFieldGenerator()724 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
725 
GeneratePrivateMembers(io::Printer * printer) const726 void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
727     io::Printer* printer) const {
728   Formatter format(printer, variables_);
729   if (implicit_weak_field_) {
730     format("::$proto_ns$::WeakRepeatedPtrField< $type$ > $name$_;\n");
731   } else {
732     format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
733   }
734 }
735 
GenerateAccessorDeclarations(io::Printer * printer) const736 void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
737     io::Printer* printer) const {
738   Formatter format(printer, variables_);
739   if (IsFieldStripped(descriptor_, options_)) {
740     format(
741         "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
742         "__builtin_trap(); }\n"
743         "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
744         "    ${1$mutable_$name$$}$() { __builtin_trap(); }\n"
745         "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { "
746         "__builtin_trap(); }\n"
747         "$deprecated_attr$$type$* ${1$add_$name$$}$() { "
748         "__builtin_trap(); }\n"
749         "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
750         "    ${1$$name$$}$() const { __builtin_trap(); }\n",
751         descriptor_);
752     return;
753   }
754   format(
755       "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
756       "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
757       "    ${1$mutable_$name$$}$();\n",
758       descriptor_);
759   if (!IsFieldStripped(descriptor_, options_)) {
760     format(
761         "private:\n"
762         "const $type$& ${1$_internal_$name$$}$(int index) const;\n"
763         "$type$* ${1$_internal_add_$name$$}$();\n"
764         "public:\n",
765         descriptor_);
766   }
767   format(
768       "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
769       "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
770       "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
771       "    ${1$$name$$}$() const;\n",
772       descriptor_);
773 }
774 
GenerateInlineAccessorDefinitions(io::Printer * printer) const775 void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
776     io::Printer* printer) const {
777   Formatter format(printer, variables_);
778   format.Set("weak", implicit_weak_field_ ? ".weak" : "");
779 
780   format(
781       "inline $type$* $classname$::mutable_$name$(int index) {\n"
782       "$annotate_mutable$"
783       // TODO(dlj): move insertion points
784       "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
785       "$type_reference_function$"
786       "  return $field$$weak$.Mutable(index);\n"
787       "}\n"
788       "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
789       "$classname$::mutable_$name$() {\n"
790       "$annotate_mutable_list$"
791       "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
792       "$type_reference_function$"
793       "  return &$field$$weak$;\n"
794       "}\n");
795 
796   if (options_.safe_boundary_check) {
797     format(
798         "inline const $type$& $classname$::_internal_$name$(int index) const "
799         "{\n"
800         "  return $field$$weak$.InternalCheckedGet(index,\n"
801         "      reinterpret_cast<const $type$&>($type_default_instance$));\n"
802         "}\n");
803   } else {
804     format(
805         "inline const $type$& $classname$::_internal_$name$(int index) const "
806         "{\n"
807         "$type_reference_function$"
808         "  return $field$$weak$.Get(index);\n"
809         "}\n");
810   }
811 
812   format(
813       "inline const $type$& $classname$::$name$(int index) const {\n"
814       "$annotate_get$"
815       "  // @@protoc_insertion_point(field_get:$full_name$)\n"
816       "  return _internal_$name$(index);\n"
817       "}\n"
818       "inline $type$* $classname$::_internal_add_$name$() {\n"
819       "  return $field$$weak$.Add();\n"
820       "}\n"
821       "inline $type$* $classname$::add_$name$() {\n"
822       "  $type$* _add = _internal_add_$name$();\n"
823       "$annotate_add_mutable$"
824       "  // @@protoc_insertion_point(field_add:$full_name$)\n"
825       "  return _add;\n"
826       "}\n");
827 
828   format(
829       "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
830       "$classname$::$name$() const {\n"
831       "$annotate_list$"
832       "  // @@protoc_insertion_point(field_list:$full_name$)\n"
833       "$type_reference_function$"
834       "  return $field$$weak$;\n"
835       "}\n");
836 }
837 
GenerateClearingCode(io::Printer * printer) const838 void RepeatedMessageFieldGenerator::GenerateClearingCode(
839     io::Printer* printer) const {
840   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
841 
842   Formatter format(printer, variables_);
843   format("$field$.Clear();\n");
844 }
845 
GenerateMergingCode(io::Printer * printer) const846 void RepeatedMessageFieldGenerator::GenerateMergingCode(
847     io::Printer* printer) const {
848   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
849 
850   Formatter format(printer, variables_);
851   format("_this->$field$.MergeFrom(from.$field$);\n");
852 }
853 
GenerateSwappingCode(io::Printer * printer) const854 void RepeatedMessageFieldGenerator::GenerateSwappingCode(
855     io::Printer* printer) const {
856   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
857 
858   Formatter format(printer, variables_);
859   format("$field$.InternalSwap(&other->$field$);\n");
860 }
861 
GenerateConstructorCode(io::Printer * printer) const862 void RepeatedMessageFieldGenerator::GenerateConstructorCode(
863     io::Printer* printer) const {
864   // Not needed for repeated fields.
865 }
866 
GenerateDestructorCode(io::Printer * printer) const867 void RepeatedMessageFieldGenerator::GenerateDestructorCode(
868     io::Printer* printer) const {
869   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
870 
871   Formatter format(printer, variables_);
872   if (implicit_weak_field_) {
873     format("$field$.~WeakRepeatedPtrField();\n");
874   } else {
875     format("$field$.~RepeatedPtrField();\n");
876   }
877 }
878 
GenerateSerializeWithCachedSizesToArray(io::Printer * printer) const879 void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
880     io::Printer* printer) const {
881   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
882 
883   Formatter format(printer, variables_);
884   if (implicit_weak_field_) {
885     format(
886         "for (auto it = this->$field$.pointer_begin(),\n"
887         "          end = this->$field$.pointer_end(); it < end; ++it) {\n");
888     if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
889       format(
890           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
891           "    InternalWrite$declared_type$($number$, "
892           "**it, (**it).GetCachedSize(), target, stream);\n");
893     } else {
894       format(
895           "  target = stream->EnsureSpace(target);\n"
896           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
897           "    InternalWrite$declared_type$($number$, **it, target, "
898           "stream);\n");
899     }
900     format("}\n");
901   } else {
902     format(
903         "for (unsigned i = 0,\n"
904         "    n = static_cast<unsigned>(this->_internal_$name$_size());"
905         " i < n; i++) {\n");
906     if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
907       format(
908           "  const auto& repfield = this->_internal_$name$(i);\n"
909           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
910           "      InternalWrite$declared_type$($number$, "
911           "repfield, repfield.GetCachedSize(), target, stream);\n"
912           "}\n");
913     } else {
914       format(
915           "  target = stream->EnsureSpace(target);\n"
916           "  target = ::$proto_ns$::internal::WireFormatLite::\n"
917           "    InternalWrite$declared_type$($number$, "
918           "this->_internal_$name$(i), target, stream);\n"
919           "}\n");
920     }
921   }
922 }
923 
GenerateByteSize(io::Printer * printer) const924 void RepeatedMessageFieldGenerator::GenerateByteSize(
925     io::Printer* printer) const {
926   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
927 
928   Formatter format(printer, variables_);
929   format(
930       "total_size += $tag_size$UL * this->_internal_$name$_size();\n"
931       "for (const auto& msg : this->$field$) {\n"
932       "  total_size +=\n"
933       "    ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
934       "}\n");
935 }
936 
GenerateIsInitialized(io::Printer * printer) const937 void RepeatedMessageFieldGenerator::GenerateIsInitialized(
938     io::Printer* printer) const {
939   GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
940 
941   if (!has_required_fields_) return;
942 
943   Formatter format(printer, variables_);
944   if (implicit_weak_field_) {
945     format(
946         "if (!::$proto_ns$::internal::AllAreInitializedWeak($field$.weak))\n"
947         "  return false;\n");
948   } else {
949     format(
950         "if (!::$proto_ns$::internal::AllAreInitialized($field$))\n"
951         "  return false;\n");
952   }
953 }
954 
955 }  // namespace cpp
956 }  // namespace compiler
957 }  // namespace protobuf
958 }  // namespace google
959