• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 // Author: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include "absl/log/absl_check.h"
17 #include "absl/memory/memory.h"
18 #include "absl/strings/str_cat.h"
19 #include "absl/strings/string_view.h"
20 #include "absl/strings/substitute.h"
21 #include "google/protobuf/compiler/cpp/field.h"
22 #include "google/protobuf/compiler/cpp/field_generators/generators.h"
23 #include "google/protobuf/compiler/cpp/helpers.h"
24 #include "google/protobuf/compiler/cpp/options.h"
25 #include "google/protobuf/descriptor.h"
26 #include "google/protobuf/descriptor.pb.h"
27 #include "google/protobuf/io/printer.h"
28 
29 namespace google {
30 namespace protobuf {
31 namespace compiler {
32 namespace cpp {
33 namespace {
34 
35 using ::google::protobuf::internal::cpp::HasHasbit;
36 using ::google::protobuf::io::AnnotationCollector;
37 using Sub = ::google::protobuf::io::Printer::Sub;
38 
Vars(const FieldDescriptor * field,const Options & opts,bool weak)39 std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts,
40                       bool weak) {
41   bool split = ShouldSplit(field, opts);
42   bool is_foreign = IsCrossFileMessage(field);
43   std::string field_name = FieldMemberName(field, split);
44   std::string qualified_type = FieldMessageTypeName(field, opts);
45   std::string default_ref =
46       QualifiedDefaultInstanceName(field->message_type(), opts);
47   std::string default_ptr =
48       QualifiedDefaultInstancePtr(field->message_type(), opts);
49   absl::string_view base = "::google::protobuf::MessageLite";
50 
51   return {
52       {"Submsg", qualified_type},
53       {"MemberType", !weak ? qualified_type : base},
54       {"CompleteType", !is_foreign ? qualified_type : base},
55       {"kDefault", default_ref},
56       {"kDefaultPtr", !weak
57                           ? default_ptr
58                           : absl::Substitute("reinterpret_cast<const $0*>($1)",
59                                              base, default_ptr)},
60       {"base_cast", !is_foreign && !weak
61                         ? ""
62                         : absl::Substitute("reinterpret_cast<$0*>", base)},
63       Sub{"weak_cast",
64           !weak ? "" : absl::Substitute("reinterpret_cast<$0*>", base)}
65           .ConditionalFunctionCall(),
66       Sub{"foreign_cast",
67           !is_foreign ? "" : absl::Substitute("reinterpret_cast<$0*>", base)}
68           .ConditionalFunctionCall(),
69       {"cast_field_", !weak ? field_name
70                             : absl::Substitute("reinterpret_cast<$0*>($1)",
71                                                qualified_type, field_name)},
72       {"Weak", weak ? "Weak" : ""},
73       {".weak", weak ? ".weak" : ""},
74       {"_weak", weak ? "_weak" : ""},
75       Sub("StrongRef",
76           !weak ? ""
77                 : absl::StrCat(
78                       StrongReferenceToType(field->message_type(), opts), ";"))
79           .WithSuffix(";"),
80   };
81 }
82 
83 class SingularMessage : public FieldGeneratorBase {
84  public:
SingularMessage(const FieldDescriptor * field,const Options & opts,MessageSCCAnalyzer * scc)85   SingularMessage(const FieldDescriptor* field, const Options& opts,
86                   MessageSCCAnalyzer* scc)
87       : FieldGeneratorBase(field, opts, scc),
88         opts_(&opts),
89         has_required_(scc->HasRequiredFields(field->message_type())),
90         has_hasbit_(HasHasbit(field)) {}
91 
92   ~SingularMessage() override = default;
93 
MakeVars() const94   std::vector<Sub> MakeVars() const override {
95     return Vars(field_, *opts_, is_weak());
96   }
97 
GeneratePrivateMembers(io::Printer * p) const98   void GeneratePrivateMembers(io::Printer* p) const override {
99     p->Emit(R"cc(
100       $MemberType$* $name$_;
101     )cc");
102   }
103 
104   bool RequiresArena(GeneratorFunction function) const override;
105 
GenerateNonInlineAccessorDefinitions(io::Printer * p) const106   void GenerateNonInlineAccessorDefinitions(io::Printer* p) const override {}
107 
108   void GenerateAccessorDeclarations(io::Printer* p) const override;
109   void GenerateInlineAccessorDefinitions(io::Printer* p) const override;
110   void GenerateClearingCode(io::Printer* p) const override;
111   void GenerateMessageClearingCode(io::Printer* p) const override;
112   void GenerateMergingCode(io::Printer* p) const override;
113   void GenerateSwappingCode(io::Printer* p) const override;
114   void GenerateDestructorCode(io::Printer* p) const override;
GenerateConstructorCode(io::Printer * p) const115   void GenerateConstructorCode(io::Printer* p) const override {}
116   void GenerateCopyConstructorCode(io::Printer* p) const override;
117   void GenerateSerializeWithCachedSizesToArray(io::Printer* p) const override;
118   void GenerateByteSize(io::Printer* p) const override;
119   void GenerateIsInitialized(io::Printer* p) const override;
120   bool NeedsIsInitialized() const override;
121   void GenerateConstexprAggregateInitializer(io::Printer* p) const override;
122   void GenerateAggregateInitializer(io::Printer* p) const override;
123   void GenerateCopyAggregateInitializer(io::Printer* p) const override;
124 
GenerateMemberConstexprConstructor(io::Printer * p) const125   void GenerateMemberConstexprConstructor(io::Printer* p) const override {
126     p->Emit("$name$_{nullptr}");
127   }
128 
GenerateMemberConstructor(io::Printer * p) const129   void GenerateMemberConstructor(io::Printer* p) const override {
130     p->Emit("$name$_{nullptr}");
131   }
132 
GenerateMemberCopyConstructor(io::Printer * p) const133   void GenerateMemberCopyConstructor(io::Printer* p) const override {
134     p->Emit(
135         "$name$_{$superclass$::CopyConstruct<$Submsg$>(arena, *from.$name$_)}");
136   }
137 
GenerateOneofCopyConstruct(io::Printer * p) const138   void GenerateOneofCopyConstruct(io::Printer* p) const override {
139     p->Emit(R"cc(
140       $field$ = $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field$);
141     )cc");
142   }
143 
144  private:
145   friend class OneofMessage;
146 
147   const Options* opts_;
148   bool has_required_;
149   bool has_hasbit_;
150 };
151 
GenerateAccessorDeclarations(io::Printer * p) const152 void SingularMessage::GenerateAccessorDeclarations(io::Printer* p) const {
153   auto vars = AnnotatedAccessors(
154       field_, {"", "set_allocated_", "unsafe_arena_set_allocated_",
155                "unsafe_arena_release_"});
156   vars.push_back(Sub{
157       "release_name",
158       SafeFunctionName(field_->containing_type(), field_, "release_"),
159   }
160                      .AnnotatedAs(field_));
161   auto v1 = p->WithVars(vars);
162   auto v2 = p->WithVars(
163       AnnotatedAccessors(field_, {"mutable_"}, AnnotationCollector::kAlias));
164 
165   p->Emit(R"cc(
166     $DEPRECATED$ const $Submsg$& $name$() const;
167     $DEPRECATED$ PROTOBUF_NODISCARD $Submsg$* $release_name$();
168     $DEPRECATED$ $Submsg$* $mutable_name$();
169     $DEPRECATED$ void $set_allocated_name$($Submsg$* value);
170     $DEPRECATED$ void $unsafe_arena_set_allocated_name$($Submsg$* value);
171     $DEPRECATED$ $Submsg$* $unsafe_arena_release_name$();
172 
173     private:
174     const $Submsg$& _internal_$name$() const;
175     $Submsg$* _internal_mutable_$name$();
176 
177     public:
178   )cc");
179 }
180 
GenerateInlineAccessorDefinitions(io::Printer * p) const181 void SingularMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
182   auto v =
183       p->WithVars({{"release_name", SafeFunctionName(field_->containing_type(),
184                                                      field_, "release_")}});
185   p->Emit(
186       {
187           {"update_hasbit",
188            [&] {
189              if (!has_hasbit_) return;
190              p->Emit(R"cc(
191                if (value != nullptr) {
192                  $set_hasbit$
193                } else {
194                  $clear_hasbit$
195                }
196              )cc");
197            }},
198       },
199       R"cc(
200         inline const $Submsg$& $Msg$::_internal_$name_internal$() const {
201           $TsanDetectConcurrentRead$;
202           $StrongRef$;
203           const $Submsg$* p = $cast_field_$;
204           return p != nullptr ? *p : reinterpret_cast<const $Submsg$&>($kDefault$);
205         }
206         inline const $Submsg$& $Msg$::$name$() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
207           $WeakDescriptorSelfPin$;
208           $annotate_get$;
209           // @@protoc_insertion_point(field_get:$pkg.Msg.field$)
210           return _internal_$name_internal$();
211         }
212         inline void $Msg$::unsafe_arena_set_allocated_$name$($Submsg$* value) {
213           $WeakDescriptorSelfPin$;
214           $TsanDetectConcurrentMutation$;
215           $PrepareSplitMessageForWrite$;
216           //~ If we're not on an arena, free whatever we were holding before.
217           //~ (If we are on arena, we can just forget the earlier pointer.)
218           if (GetArena() == nullptr) {
219             delete reinterpret_cast<$pb$::MessageLite*>($field_$);
220           }
221           $field_$ = reinterpret_cast<$MemberType$*>(value);
222           $update_hasbit$;
223           $annotate_set$;
224           // @@protoc_insertion_point(field_unsafe_arena_set_allocated:$pkg.Msg.field$)
225         }
226         inline $Submsg$* $Msg$::$release_name$() {
227           $WeakDescriptorSelfPin$;
228           $TsanDetectConcurrentMutation$;
229           $StrongRef$;
230           $annotate_release$;
231           $PrepareSplitMessageForWrite$;
232 
233           $clear_hasbit$;
234           $Submsg$* released = $cast_field_$;
235           $field_$ = nullptr;
236           if ($pbi$::DebugHardenForceCopyInRelease()) {
237             auto* old = reinterpret_cast<$pb$::MessageLite*>(released);
238             released = $pbi$::DuplicateIfNonNull(released);
239             if (GetArena() == nullptr) {
240               delete old;
241             }
242           } else {
243             if (GetArena() != nullptr) {
244               released = $pbi$::DuplicateIfNonNull(released);
245             }
246           }
247           return released;
248         }
249         inline $Submsg$* $Msg$::unsafe_arena_release_$name$() {
250           $WeakDescriptorSelfPin$;
251           $TsanDetectConcurrentMutation$;
252           $annotate_release$;
253           // @@protoc_insertion_point(field_release:$pkg.Msg.field$)
254           $StrongRef$;
255           $PrepareSplitMessageForWrite$;
256 
257           $clear_hasbit$;
258           $Submsg$* temp = $cast_field_$;
259           $field_$ = nullptr;
260           return temp;
261         }
262         inline $Submsg$* $Msg$::_internal_mutable_$name_internal$() {
263           $TsanDetectConcurrentMutation$;
264           $StrongRef$;
265           if ($field_$ == nullptr) {
266             auto* p = $superclass$::DefaultConstruct<$Submsg$>(GetArena());
267             $field_$ = reinterpret_cast<$MemberType$*>(p);
268           }
269           return $cast_field_$;
270         }
271         inline $Submsg$* $Msg$::mutable_$name$() ABSL_ATTRIBUTE_LIFETIME_BOUND {
272           //~ TODO: add tests to make sure all write accessors are
273           //~ able to prepare split message allocation.
274           $WeakDescriptorSelfPin$;
275           $PrepareSplitMessageForWrite$;
276           $set_hasbit$;
277           $Submsg$* _msg = _internal_mutable_$name_internal$();
278           $annotate_mutable$;
279           // @@protoc_insertion_point(field_mutable:$pkg.Msg.field$)
280           return _msg;
281         }
282         //~ We handle the most common case inline, and delegate less common
283         //~ cases to the slow fallback function.
284         inline void $Msg$::set_allocated_$name$($Submsg$* value) {
285           $WeakDescriptorSelfPin$;
286           $pb$::Arena* message_arena = GetArena();
287           $TsanDetectConcurrentMutation$;
288           $PrepareSplitMessageForWrite$;
289           if (message_arena == nullptr) {
290             delete $base_cast$($field_$);
291           }
292 
293           if (value != nullptr) {
294             //~ When $Submsg$ is a cross-file type, have to read the arena
295             //~ through the virtual method, because the type isn't defined in
296             //~ this file, only forward-declared.
297             $pb$::Arena* submessage_arena = $base_cast$(value)->GetArena();
298             if (message_arena != submessage_arena) {
299               value = $pbi$::GetOwnedMessage(message_arena, value, submessage_arena);
300             }
301             $set_hasbit$;
302           } else {
303             $clear_hasbit$;
304           }
305 
306           $field_$ = reinterpret_cast<$MemberType$*>(value);
307           $annotate_set$;
308           // @@protoc_insertion_point(field_set_allocated:$pkg.Msg.field$)
309         }
310       )cc");
311 }
312 
GenerateClearingCode(io::Printer * p) const313 void SingularMessage::GenerateClearingCode(io::Printer* p) const {
314   ABSL_CHECK(has_hasbit_);
315   p->Emit(
316       R"cc(
317         if ($field_$ != nullptr) $field_$->Clear();
318       )cc");
319 }
320 
GenerateMessageClearingCode(io::Printer * p) const321 void SingularMessage::GenerateMessageClearingCode(io::Printer* p) const {
322   ABSL_CHECK(has_hasbit_);
323   p->Emit(
324       R"cc(
325         $DCHK$($field_$ != nullptr);
326         $field_$->Clear();
327       )cc");
328 }
329 
RequiresArena(GeneratorFunction function) const330 bool SingularMessage::RequiresArena(GeneratorFunction function) const {
331   switch (function) {
332     case GeneratorFunction::kMergeFrom:
333       return !should_split();
334   }
335   return false;
336 }
337 
GenerateMergingCode(io::Printer * p) const338 void SingularMessage::GenerateMergingCode(io::Printer* p) const {
339   if (is_weak()) {
340     p->Emit(
341         R"cc(
342           if (_this->$field_$ == nullptr) {
343             _this->$field_$ = from.$field_$->New(arena);
344           }
345           _this->$field_$->CheckTypeAndMergeFrom(*from.$field_$);
346         )cc");
347   } else if (should_split()) {
348     p->Emit(
349         R"cc(
350           _this->_internal_mutable_$name$()->$Submsg$::MergeFrom(
351               from._internal_$name$());
352         )cc");
353   } else {
354     // Important: we set `hasbits` after we copied the field. There are cases
355     // where people assign root values to child values or vice versa which
356     // are not always checked, so we delay this change becoming 'visible'
357     // until after we copied the message.
358     // TODO enforces this as undefined behavior in debug builds.
359     p->Emit(R"cc(
360       $DCHK$(from.$field_$ != nullptr);
361       if (_this->$field_$ == nullptr) {
362         _this->$field_$ =
363             $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$);
364       } else {
365         _this->$field_$->MergeFrom(*from.$field_$);
366       }
367     )cc");
368   }
369 }
370 
GenerateSwappingCode(io::Printer * p) const371 void SingularMessage::GenerateSwappingCode(io::Printer* p) const {
372   p->Emit("swap($field_$, other->$field_$);\n");
373 }
374 
GenerateDestructorCode(io::Printer * p) const375 void SingularMessage::GenerateDestructorCode(io::Printer* p) const {
376   if (should_split()) {
377     p->Emit(R"cc(
378       delete $cached_split_ptr$->$name$_;
379     )cc");
380   } else {
381     p->Emit(R"cc(
382       delete this_.$field_$;
383     )cc");
384   }
385 }
386 
GenerateCopyConstructorCode(io::Printer * p) const387 void SingularMessage::GenerateCopyConstructorCode(io::Printer* p) const {
388   ABSL_CHECK(has_hasbit_);
389   p->Emit(R"cc(
390     if ((from.$has_hasbit$) != 0) {
391       _this->$field_$ =
392           $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$);
393     }
394   )cc");
395 }
396 
GenerateSerializeWithCachedSizesToArray(io::Printer * p) const397 void SingularMessage::GenerateSerializeWithCachedSizesToArray(
398     io::Printer* p) const {
399   if (!is_group()) {
400     p->Emit(R"cc(
401       target = $pbi$::WireFormatLite::InternalWrite$declared_type$(
402           $number$, *this_.$field_$, this_.$field_$->GetCachedSize(), target,
403           stream);
404     )cc");
405   } else {
406     p->Emit(R"cc(
407       target = stream->EnsureSpace(target);
408       target = $pbi$::WireFormatLite::InternalWrite$declared_type$(
409           $number$, *this_.$field_$, target, stream);
410     )cc");
411   }
412 }
413 
GenerateByteSize(io::Printer * p) const414 void SingularMessage::GenerateByteSize(io::Printer* p) const {
415   p->Emit(R"cc(
416     total_size += $tag_size$ +
417                   $pbi$::WireFormatLite::$declared_type$Size(*this_.$field_$);
418   )cc");
419 }
420 
GenerateIsInitialized(io::Printer * p) const421 void SingularMessage::GenerateIsInitialized(io::Printer* p) const {
422   if (!NeedsIsInitialized()) return;
423 
424   if (HasHasbit(field_)) {
425     p->Emit(R"cc(
426       if ((this_.$has_hasbit$) != 0) {
427         if (!this_.$field_$->IsInitialized()) return false;
428       }
429     )cc");
430   } else {
431     p->Emit(R"cc(
432       if (this_._internal_has_$name$()) {
433         if (!this_.$field_$->IsInitialized()) return false;
434       }
435     )cc");
436   }
437 }
438 
NeedsIsInitialized() const439 bool SingularMessage::NeedsIsInitialized() const { return has_required_; }
440 
GenerateConstexprAggregateInitializer(io::Printer * p) const441 void SingularMessage::GenerateConstexprAggregateInitializer(
442     io::Printer* p) const {
443   p->Emit(R"cc(
444     /*decltype($field_$)*/ nullptr,
445   )cc");
446 }
447 
GenerateCopyAggregateInitializer(io::Printer * p) const448 void SingularMessage::GenerateCopyAggregateInitializer(io::Printer* p) const {
449   p->Emit(R"cc(
450     decltype($field_$){nullptr},
451   )cc");
452 }
453 
GenerateAggregateInitializer(io::Printer * p) const454 void SingularMessage::GenerateAggregateInitializer(io::Printer* p) const {
455   if (should_split()) {
456     p->Emit(R"cc(
457       decltype(Impl_::Split::$name$_){nullptr},
458     )cc");
459   } else {
460     p->Emit(R"cc(
461       decltype($field_$){nullptr},
462     )cc");
463   }
464 }
465 
466 class OneofMessage : public SingularMessage {
467  public:
OneofMessage(const FieldDescriptor * descriptor,const Options & options,MessageSCCAnalyzer * scc_analyzer)468   OneofMessage(const FieldDescriptor* descriptor, const Options& options,
469                MessageSCCAnalyzer* scc_analyzer)
470       : SingularMessage(descriptor, options, scc_analyzer) {}
471 
472   ~OneofMessage() override = default;
473 
474   void GenerateInlineAccessorDefinitions(io::Printer* p) const override;
475   void GenerateNonInlineAccessorDefinitions(io::Printer* p) const override;
476   void GenerateClearingCode(io::Printer* p) const override;
477   void GenerateMessageClearingCode(io::Printer* p) const override;
478   void GenerateSwappingCode(io::Printer* p) const override;
479   void GenerateDestructorCode(io::Printer* p) const override;
480   void GenerateConstructorCode(io::Printer* p) const override;
481   void GenerateCopyConstructorCode(io::Printer* p) const override;
482   void GenerateIsInitialized(io::Printer* p) const override;
483   bool NeedsIsInitialized() const override;
484   void GenerateMergingCode(io::Printer* p) const override;
485   bool RequiresArena(GeneratorFunction func) const override;
486 };
487 
GenerateNonInlineAccessorDefinitions(io::Printer * p) const488 void OneofMessage::GenerateNonInlineAccessorDefinitions(io::Printer* p) const {
489   p->Emit(R"cc(
490     void $Msg$::set_allocated_$name$($Submsg$* $name$) {
491       $pb$::Arena* message_arena = GetArena();
492       clear_$oneof_name$();
493       if ($name$) {
494         $pb$::Arena* submessage_arena = $foreign_cast$($name$)->GetArena();
495         if (message_arena != submessage_arena) {
496           $name$ = $pbi$::GetOwnedMessage(message_arena, $name$, submessage_arena);
497         }
498         set_has_$name$();
499         $field_$ = $name$;
500       }
501       $annotate_set$;
502       // @@protoc_insertion_point(field_set_allocated:$pkg.Msg.field$)
503     }
504   )cc");
505 }
506 
GenerateInlineAccessorDefinitions(io::Printer * p) const507 void OneofMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
508   auto v =
509       p->WithVars({{"release_name", SafeFunctionName(field_->containing_type(),
510                                                      field_, "release_")}});
511 
512   p->Emit(R"cc(
513     inline $Submsg$* $Msg$::$release_name$() {
514       $WeakDescriptorSelfPin$;
515       $annotate_release$;
516       // @@protoc_insertion_point(field_release:$pkg.Msg.field$)
517       $StrongRef$;
518       if ($has_field$) {
519         clear_has_$oneof_name$();
520         auto* temp = $cast_field_$;
521         if (GetArena() != nullptr) {
522           temp = $pbi$::DuplicateIfNonNull(temp);
523         }
524         $field_$ = nullptr;
525         return temp;
526       } else {
527         return nullptr;
528       }
529     }
530   )cc");
531   p->Emit(R"cc(
532     inline const $Submsg$& $Msg$::_internal_$name_internal$() const {
533       $StrongRef$;
534       return $has_field$ ? *$cast_field_$ : reinterpret_cast<$Submsg$&>($kDefault$);
535     }
536   )cc");
537   p->Emit(R"cc(
538     inline const $Submsg$& $Msg$::$name$() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
539       $WeakDescriptorSelfPin$;
540       $annotate_get$;
541       // @@protoc_insertion_point(field_get:$pkg.Msg.field$)
542       return _internal_$name_internal$();
543     }
544   )cc");
545   p->Emit(R"cc(
546     inline $Submsg$* $Msg$::unsafe_arena_release_$name$() {
547       $WeakDescriptorSelfPin$;
548       $annotate_release$;
549       // @@protoc_insertion_point(field_unsafe_arena_release:$pkg.Msg.field$)
550       $StrongRef$;
551       if ($has_field$) {
552         clear_has_$oneof_name$();
553         auto* temp = $cast_field_$;
554         $field_$ = nullptr;
555         return temp;
556       } else {
557         return nullptr;
558       }
559     }
560   )cc");
561   p->Emit(R"cc(
562     inline void $Msg$::unsafe_arena_set_allocated_$name$($Submsg$* value) {
563       $WeakDescriptorSelfPin$;
564       // We rely on the oneof clear method to free the earlier contents
565       // of this oneof. We can directly use the pointer we're given to
566       // set the new value.
567       clear_$oneof_name$();
568       if (value) {
569         set_has_$name_internal$();
570         $field_$ = $weak_cast$(value);
571       }
572       $annotate_set$;
573       // @@protoc_insertion_point(field_unsafe_arena_set_allocated:$pkg.Msg.field$)
574     }
575   )cc");
576   p->Emit(R"cc(
577     inline $Submsg$* $Msg$::_internal_mutable_$name_internal$() {
578       $StrongRef$;
579       if ($not_has_field$) {
580         clear_$oneof_name$();
581         set_has_$name_internal$();
582         $field_$ =
583             $weak_cast$($superclass$::DefaultConstruct<$Submsg$>(GetArena()));
584       }
585       return $cast_field_$;
586     }
587   )cc");
588   p->Emit(R"cc(
589     inline $Submsg$* $Msg$::mutable_$name$() ABSL_ATTRIBUTE_LIFETIME_BOUND {
590       $WeakDescriptorSelfPin$;
591       $Submsg$* _msg = _internal_mutable_$name_internal$();
592       $annotate_mutable$;
593       // @@protoc_insertion_point(field_mutable:$pkg.Msg.field$)
594       return _msg;
595     }
596   )cc");
597 }
598 
GenerateClearingCode(io::Printer * p) const599 void OneofMessage::GenerateClearingCode(io::Printer* p) const {
600   p->Emit({{"poison_or_clear",
601             [&] {
602               if (HasDescriptorMethods(field_->file(), options_)) {
603                 p->Emit(R"cc(
604                   $pbi$::MaybePoisonAfterClear($field_$);
605                 )cc");
606               } else {
607                 p->Emit(R"cc(
608                   if ($field_$ != nullptr) {
609                     $field_$->Clear();
610                   }
611                 )cc");
612               }
613             }}},
614           R"cc(
615             if (GetArena() == nullptr) {
616               delete $field_$;
617             } else if ($pbi$::DebugHardenClearOneofMessageOnArena()) {
618               $poison_or_clear$;
619             }
620           )cc");
621 }
622 
GenerateMessageClearingCode(io::Printer * p) const623 void OneofMessage::GenerateMessageClearingCode(io::Printer* p) const {
624   GenerateClearingCode(p);
625 }
626 
GenerateSwappingCode(io::Printer * p) const627 void OneofMessage::GenerateSwappingCode(io::Printer* p) const {
628   // Don't print any swapping code. Swapping the union will swap this field.
629 }
630 
GenerateDestructorCode(io::Printer * p) const631 void OneofMessage::GenerateDestructorCode(io::Printer* p) const {
632   // We inherit from SingularMessage, so we need to override the default
633   // behavior.
634 }
635 
GenerateConstructorCode(io::Printer * p) const636 void OneofMessage::GenerateConstructorCode(io::Printer* p) const {
637   // Don't print any constructor code. The field is in a union. We allocate
638   // space only when this field is used.
639 }
640 
GenerateCopyConstructorCode(io::Printer * p) const641 void OneofMessage::GenerateCopyConstructorCode(io::Printer* p) const {
642   ABSL_CHECK(!has_hasbit_);
643   p->Emit(R"cc(
644     if (from._internal_has_$name$()) {
645       _this->$field_$ =
646           $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$);
647     }
648   )cc");
649 }
650 
GenerateIsInitialized(io::Printer * p) const651 void OneofMessage::GenerateIsInitialized(io::Printer* p) const {
652   if (!NeedsIsInitialized()) return;
653 
654   p->Emit(R"cc(
655     if (this_.$has_field$ && !this_.$field_$->IsInitialized())
656       return false;
657   )cc");
658 }
659 
NeedsIsInitialized() const660 bool OneofMessage::NeedsIsInitialized() const { return has_required_; }
661 
GenerateMergingCode(io::Printer * p) const662 void OneofMessage::GenerateMergingCode(io::Printer* p) const {
663   if (is_weak()) {
664     p->Emit(R"cc(
665       if (oneof_needs_init) {
666         _this->$field_$ = from.$field_$->New(arena);
667       }
668       _this->$field_$->CheckTypeAndMergeFrom(*from.$field_$);
669     )cc");
670   } else {
671     p->Emit(R"cc(
672       if (oneof_needs_init) {
673         _this->$field_$ =
674             $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$);
675       } else {
676         _this->$field_$->MergeFrom(from._internal_$name$());
677       }
678     )cc");
679   }
680 }
681 
RequiresArena(GeneratorFunction func) const682 bool OneofMessage::RequiresArena(GeneratorFunction func) const {
683   switch (func) {
684     case GeneratorFunction::kMergeFrom:
685       return true;
686   }
687   return false;
688 }
689 
690 class RepeatedMessage : public FieldGeneratorBase {
691  public:
RepeatedMessage(const FieldDescriptor * field,const Options & opts,MessageSCCAnalyzer * scc)692   RepeatedMessage(const FieldDescriptor* field, const Options& opts,
693                   MessageSCCAnalyzer* scc)
694       : FieldGeneratorBase(field, opts, scc),
695         opts_(&opts),
696         has_required_(scc->HasRequiredFields(field->message_type())) {}
697 
698   ~RepeatedMessage() override = default;
699 
MakeVars() const700   std::vector<Sub> MakeVars() const override {
701     return Vars(field_, *opts_, is_weak());
702   }
703 
704   void GeneratePrivateMembers(io::Printer* p) const override;
705   void GenerateAccessorDeclarations(io::Printer* p) const override;
706   void GenerateInlineAccessorDefinitions(io::Printer* p) const override;
707   void GenerateClearingCode(io::Printer* p) const override;
708   void GenerateMergingCode(io::Printer* p) const override;
709   void GenerateSwappingCode(io::Printer* p) const override;
710   void GenerateConstructorCode(io::Printer* p) const override;
711   void GenerateCopyConstructorCode(io::Printer* p) const override;
712   void GenerateDestructorCode(io::Printer* p) const override;
713   void GenerateSerializeWithCachedSizesToArray(io::Printer* p) const override;
714   void GenerateByteSize(io::Printer* p) const override;
715   void GenerateIsInitialized(io::Printer* p) const override;
716   bool NeedsIsInitialized() const override;
717 
718  private:
719   const Options* opts_;
720   bool has_required_;
721 };
722 
GeneratePrivateMembers(io::Printer * p) const723 void RepeatedMessage::GeneratePrivateMembers(io::Printer* p) const {
724   if (should_split()) {
725     p->Emit(R"cc(
726       $pbi$::RawPtr<$pb$::$Weak$RepeatedPtrField<$Submsg$>> $name$_;
727     )cc");
728   } else {
729     p->Emit("$pb$::$Weak$RepeatedPtrField< $Submsg$ > $name$_;\n");
730   }
731 }
732 
GenerateAccessorDeclarations(io::Printer * p) const733 void RepeatedMessage::GenerateAccessorDeclarations(io::Printer* p) const {
734   auto v = p->WithVars(
735       AnnotatedAccessors(field_, {"", "_internal_", "_internal_mutable_"}));
736   auto vs = p->WithVars(
737       AnnotatedAccessors(field_, {"add_"}, io::AnnotationCollector::kSet));
738   auto vm = p->WithVars(AnnotatedAccessors(field_, {"mutable_"},
739                                            io::AnnotationCollector::kAlias));
740 
741   p->Emit(R"cc(
742     $DEPRECATED$ $Submsg$* $mutable_name$(int index);
743     $DEPRECATED$ $pb$::RepeatedPtrField<$Submsg$>* $mutable_name$();
744 
745     private:
746     const $pb$::RepeatedPtrField<$Submsg$>& $_internal_name$() const;
747     $pb$::RepeatedPtrField<$Submsg$>* $_internal_mutable_name$();
748   )cc");
749   if (is_weak()) {
750     p->Emit(R"cc(
751       const $pb$::WeakRepeatedPtrField<$Submsg$>& _internal_weak_$name$() const;
752       $pb$::WeakRepeatedPtrField<$Submsg$>* _internal_mutable_weak_$name$();
753     )cc");
754   }
755   p->Emit(R"cc(
756     public:
757     $DEPRECATED$ const $Submsg$& $name$(int index) const;
758     $DEPRECATED$ $Submsg$* $add_name$();
759     $DEPRECATED$ const $pb$::RepeatedPtrField<$Submsg$>& $name$() const;
760   )cc");
761 }
762 
GenerateInlineAccessorDefinitions(io::Printer * p) const763 void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const {
764   // TODO: move insertion points
765   p->Emit(R"cc(
766     inline $Submsg$* $Msg$::mutable_$name$(int index)
767         ABSL_ATTRIBUTE_LIFETIME_BOUND {
768       $WeakDescriptorSelfPin$;
769       $annotate_mutable$;
770       // @@protoc_insertion_point(field_mutable:$pkg.Msg.field$)
771       $StrongRef$;
772       return _internal_mutable_$name_internal$()->Mutable(index);
773     }
774   )cc");
775   p->Emit(R"cc(
776     inline $pb$::RepeatedPtrField<$Submsg$>* $Msg$::mutable_$name$()
777         ABSL_ATTRIBUTE_LIFETIME_BOUND {
778       $WeakDescriptorSelfPin$;
779       $annotate_mutable_list$;
780       // @@protoc_insertion_point(field_mutable_list:$pkg.Msg.field$)
781       $StrongRef$;
782       $TsanDetectConcurrentMutation$;
783       return _internal_mutable_$name_internal$();
784     }
785   )cc");
786   p->Emit(
787       {
788           {"Get", opts_->safe_boundary_check ? "InternalCheckedGet" : "Get"},
789           {"GetExtraArg",
790            [&] {
791              p->Emit(opts_->safe_boundary_check
792                          ? ", reinterpret_cast<const $Submsg$&>($kDefault$)"
793                          : "");
794            }},
795       },
796       R"cc(
797         inline const $Submsg$& $Msg$::$name$(int index) const
798             ABSL_ATTRIBUTE_LIFETIME_BOUND {
799           $WeakDescriptorSelfPin$;
800           $annotate_get$;
801           // @@protoc_insertion_point(field_get:$pkg.Msg.field$)
802           $StrongRef$;
803           return _internal_$name_internal$().$Get$(index$GetExtraArg$);
804         }
805       )cc");
806   p->Emit(R"cc(
807     inline $Submsg$* $Msg$::add_$name$() ABSL_ATTRIBUTE_LIFETIME_BOUND {
808       $WeakDescriptorSelfPin$;
809       $TsanDetectConcurrentMutation$;
810       $Submsg$* _add = _internal_mutable_$name_internal$()->Add();
811       $annotate_add_mutable$;
812       // @@protoc_insertion_point(field_add:$pkg.Msg.field$)
813       return _add;
814     }
815   )cc");
816   p->Emit(R"cc(
817     inline const $pb$::RepeatedPtrField<$Submsg$>& $Msg$::$name$() const
818         ABSL_ATTRIBUTE_LIFETIME_BOUND {
819       $WeakDescriptorSelfPin$;
820       $annotate_list$;
821       // @@protoc_insertion_point(field_list:$pkg.Msg.field$)
822       $StrongRef$;
823       return _internal_$name_internal$();
824     }
825   )cc");
826 
827   if (should_split()) {
828     p->Emit(R"cc(
829       inline const $pb$::$Weak$RepeatedPtrField<$Submsg$>&
830       $Msg$::_internal$_weak$_$name_internal$() const {
831         $TsanDetectConcurrentRead$;
832         return *$field_$;
833       }
834       inline $pb$::$Weak$RepeatedPtrField<$Submsg$>*
835       $Msg$::_internal_mutable$_weak$_$name_internal$() {
836         $TsanDetectConcurrentRead$;
837         $PrepareSplitMessageForWrite$;
838         if ($field_$.IsDefault()) {
839           $field_$.Set($superclass$::DefaultConstruct<
840                        $pb$::$Weak$RepeatedPtrField<$Submsg$>>(GetArena()));
841         }
842         return $field_$.Get();
843       }
844     )cc");
845   } else {
846     p->Emit(R"cc(
847       inline const $pb$::$Weak$RepeatedPtrField<$Submsg$>&
848       $Msg$::_internal$_weak$_$name_internal$() const {
849         $TsanDetectConcurrentRead$;
850         return $field_$;
851       }
852       inline $pb$::$Weak$RepeatedPtrField<$Submsg$>*
853       $Msg$::_internal_mutable$_weak$_$name_internal$() {
854         $TsanDetectConcurrentRead$;
855         return &$field_$;
856       }
857     )cc");
858   }
859   if (is_weak()) {
860     p->Emit(R"cc(
861       inline const $pb$::RepeatedPtrField<$Submsg$>&
862       $Msg$::_internal_$name_internal$() const {
863         return _internal_weak_$name_internal$().weak;
864       }
865       inline $pb$::RepeatedPtrField<$Submsg$>*
866       $Msg$::_internal_mutable_$name_internal$() {
867         return &_internal_mutable_weak_$name_internal$()->weak;
868       }
869     )cc");
870   }
871 }
872 
GenerateClearingCode(io::Printer * p) const873 void RepeatedMessage::GenerateClearingCode(io::Printer* p) const {
874   if (should_split()) {
875     p->Emit("$field_$.ClearIfNotDefault();\n");
876   } else {
877     p->Emit("$field_$.Clear();\n");
878   }
879 }
880 
GenerateMergingCode(io::Printer * p) const881 void RepeatedMessage::GenerateMergingCode(io::Printer* p) const {
882   // TODO: experiment with simplifying this to be
883   // `if (!from.empty()) { body(); }` for both split and non-split cases.
884   auto body = [&] {
885     p->Emit(R"cc(
886       _this->_internal_mutable$_weak$_$name$()->MergeFrom(
887           from._internal$_weak$_$name$());
888     )cc");
889   };
890   if (!should_split()) {
891     body();
892   } else {
893     p->Emit({{"body", body}}, R"cc(
894       if (!from.$field_$.IsDefault()) {
895         $body$;
896       }
897     )cc");
898   }
899 }
900 
GenerateSwappingCode(io::Printer * p) const901 void RepeatedMessage::GenerateSwappingCode(io::Printer* p) const {
902   ABSL_CHECK(!should_split());
903   p->Emit(R"cc(
904     $field_$.InternalSwap(&other->$field_$);
905   )cc");
906 }
907 
GenerateConstructorCode(io::Printer * p) const908 void RepeatedMessage::GenerateConstructorCode(io::Printer* p) const {
909   // Not needed for repeated fields.
910 }
911 
GenerateCopyConstructorCode(io::Printer * p) const912 void RepeatedMessage::GenerateCopyConstructorCode(io::Printer* p) const {
913   // TODO: For split repeated fields we might want to use type
914   // erasure to reduce binary size costs.
915   if (should_split()) {
916     p->Emit(R"cc(
917       if (!from._internal$_weak$_$name$().empty()) {
918         _internal_mutable$_weak$_$name$()->MergeFrom(from._internal$_weak$_$name$());
919       }
920     )cc");
921   }
922 }
923 
GenerateDestructorCode(io::Printer * p) const924 void RepeatedMessage::GenerateDestructorCode(io::Printer* p) const {
925   if (should_split()) {
926     p->Emit(R"cc(
927       this_.$field_$.DeleteIfNotDefault();
928     )cc");
929   }
930 }
931 
GenerateSerializeWithCachedSizesToArray(io::Printer * p) const932 void RepeatedMessage::GenerateSerializeWithCachedSizesToArray(
933     io::Printer* p) const {
934   if (is_weak()) {
935     p->Emit({{"serialize_field",
936               [&] {
937                 if (field_->type() == FieldDescriptor::TYPE_MESSAGE) {
938                   p->Emit(
939                       R"cc(
940                         target =
941                             $pbi$::WireFormatLite::InternalWrite$declared_type$(
942                                 $number$, **it, (**it).GetCachedSize(), target,
943                                 stream);
944                       )cc");
945                 } else {
946                   p->Emit(
947                       R"cc(
948                         target = stream->EnsureSpace(target);
949                         target =
950                             $pbi$::WireFormatLite::InternalWrite$declared_type$(
951                                 $number$, **it, target, stream);
952                       )cc");
953                 }
954               }}},
955             R"cc(
956               for (auto it = this_.$field_$.pointer_begin(),
957                         end = this_.$field_$.pointer_end();
958                    it < end; ++it) {
959                 $serialize_field$;
960               }
961             )cc");
962   } else {
963     p->Emit({{"serialize_field",
964               [&] {
965                 if (field_->type() == FieldDescriptor::TYPE_MESSAGE) {
966                   p->Emit(
967                       R"cc(
968                         const auto& repfield = this_._internal_$name$().Get(i);
969                         target =
970                             $pbi$::WireFormatLite::InternalWrite$declared_type$(
971                                 $number$, repfield, repfield.GetCachedSize(),
972                                 target, stream);
973                       )cc");
974                 } else {
975                   p->Emit(
976                       R"cc(
977                         target = stream->EnsureSpace(target);
978                         target =
979                             $pbi$::WireFormatLite::InternalWrite$declared_type$(
980                                 $number$, this_._internal_$name$().Get(i),
981                                 target, stream);
982                       )cc");
983                 }
984               }}},
985             R"cc(
986               for (unsigned i = 0, n = static_cast<unsigned>(
987                                        this_._internal_$name$_size());
988                    i < n; i++) {
989                 $serialize_field$;
990               }
991             )cc");
992   }
993 }
994 
GenerateByteSize(io::Printer * p) const995 void RepeatedMessage::GenerateByteSize(io::Printer* p) const {
996   p->Emit(
997       R"cc(
998         total_size += $tag_size$UL * this_._internal_$name$_size();
999         for (const auto& msg : this_._internal$_weak$_$name$()) {
1000           total_size += $pbi$::WireFormatLite::$declared_type$Size(msg);
1001         }
1002       )cc");
1003 }
1004 
GenerateIsInitialized(io::Printer * p) const1005 void RepeatedMessage::GenerateIsInitialized(io::Printer* p) const {
1006   if (!NeedsIsInitialized()) return;
1007 
1008   if (is_weak()) {
1009     p->Emit(
1010         R"cc(
1011           if (!$pbi$::AllAreInitializedWeak(this_.$field_$.weak))
1012             return false;
1013         )cc");
1014   } else {
1015     p->Emit(
1016         R"cc(
1017           if (!$pbi$::AllAreInitialized(this_._internal_$name$()))
1018             return false;
1019         )cc");
1020   }
1021 }
1022 
NeedsIsInitialized() const1023 bool RepeatedMessage::NeedsIsInitialized() const { return has_required_; }
1024 }  // namespace
1025 
MakeSinguarMessageGenerator(const FieldDescriptor * desc,const Options & options,MessageSCCAnalyzer * scc)1026 std::unique_ptr<FieldGeneratorBase> MakeSinguarMessageGenerator(
1027     const FieldDescriptor* desc, const Options& options,
1028     MessageSCCAnalyzer* scc) {
1029   return absl::make_unique<SingularMessage>(desc, options, scc);
1030 }
1031 
MakeRepeatedMessageGenerator(const FieldDescriptor * desc,const Options & options,MessageSCCAnalyzer * scc)1032 std::unique_ptr<FieldGeneratorBase> MakeRepeatedMessageGenerator(
1033     const FieldDescriptor* desc, const Options& options,
1034     MessageSCCAnalyzer* scc) {
1035   return absl::make_unique<RepeatedMessage>(desc, options, scc);
1036 }
1037 
MakeOneofMessageGenerator(const FieldDescriptor * desc,const Options & options,MessageSCCAnalyzer * scc)1038 std::unique_ptr<FieldGeneratorBase> MakeOneofMessageGenerator(
1039     const FieldDescriptor* desc, const Options& options,
1040     MessageSCCAnalyzer* scc) {
1041   return absl::make_unique<OneofMessage>(desc, options, scc);
1042 }
1043 
1044 }  // namespace cpp
1045 }  // namespace compiler
1046 }  // namespace protobuf
1047 }  // namespace google
1048