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