1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32// Based on original Protocol Buffers design by
33// Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <google/protobuf/compiler/cpp/message_field.h>
36
37#include <google/protobuf/io/printer.h>
38#include <google/protobuf/compiler/cpp/field.h>
39#include <google/protobuf/compiler/cpp/helpers.h>
40
41#include <google/protobuf/stubs/strutil.h>
42
43namespace google {
44namespace protobuf {
45namespace compiler {
46namespace cpp {
47
48namespace {
49std::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
59void 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(field: descriptor, options);
64 (*variables)["casted_member"] = ReinterpretCast(
65 type: (*variables)["type"] + "*", expression: (*variables)["field"], implicit_weak_field: implicit_weak);
66 (*variables)["casted_member_const"] =
67 ReinterpretCast(type: "const " + (*variables)["type"] + "&",
68 expression: "*" + (*variables)["field"], implicit_weak_field: implicit_weak);
69 (*variables)["type_default_instance"] =
70 QualifiedDefaultInstanceName(descriptor: descriptor->message_type(), options);
71 (*variables)["type_default_instance_ptr"] = ReinterpretCast(
72 type: "const ::PROTOBUF_NAMESPACE_ID::MessageLite*",
73 expression: QualifiedDefaultInstancePtr(descriptor: descriptor->message_type(), options),
74 implicit_weak_field: 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: descriptor->containing_type(), field: descriptor, prefix: "release_");
85 (*variables)["full_name"] = descriptor->full_name();
86}
87
88} // namespace
89
90// ===================================================================
91
92MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
93 const Options& options,
94 MessageSCCAnalyzer* scc_analyzer)
95 : FieldGenerator(descriptor, options),
96 implicit_weak_field_(
97 IsImplicitWeakField(field: descriptor, options, scc_analyzer)),
98 has_required_fields_(
99 scc_analyzer->HasRequiredFields(descriptor: descriptor->message_type())) {
100 SetMessageVariables(descriptor, options, implicit_weak: implicit_weak_field_, variables: &variables_);
101}
102
103MessageFieldGenerator::~MessageFieldGenerator() {}
104
105void 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
114void 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
160void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
161 io::Printer* printer) const {}
162
163void 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(field: 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(field: 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
310void 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
324void 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(field: 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
375void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
376 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
377
378 Formatter format(printer, variables_);
379 if (!HasHasbit(field: 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
392void MessageFieldGenerator::GenerateMessageClearingCode(
393 io::Printer* printer) const {
394 GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
395
396 Formatter format(printer, variables_);
397 if (!HasHasbit(field: 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
412void 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
427void 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
434void 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(field: descriptor_, options: options_)) {
447 format("delete $cached_split_ptr$->$name$_;\n");
448 return;
449 }
450 format("delete $field$;\n");
451}
452
453void 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
464void 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
483void 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
493void 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
505void MessageFieldGenerator::GenerateConstexprAggregateInitializer(
506 io::Printer* printer) const {
507 Formatter format(printer, variables_);
508 format("/*decltype($field$)*/nullptr");
509}
510
511void MessageFieldGenerator::GenerateCopyAggregateInitializer(
512 io::Printer* printer) const {
513 Formatter format(printer, variables_);
514 format("decltype($field$){nullptr}");
515}
516
517void MessageFieldGenerator::GenerateAggregateInitializer(
518 io::Printer* printer) const {
519 Formatter format(printer, variables_);
520 if (ShouldSplit(field: descriptor_, options: options_)) {
521 format("decltype(Impl_::Split::$name$_){nullptr}");
522 return;
523 }
524 format("decltype($field$){nullptr}");
525}
526
527// ===================================================================
528
529MessageOneofFieldGenerator::MessageOneofFieldGenerator(
530 const FieldDescriptor* descriptor, const Options& options,
531 MessageSCCAnalyzer* scc_analyzer)
532 : MessageFieldGenerator(descriptor, options, scc_analyzer) {
533 SetCommonOneofFieldVariables(descriptor, variables: &variables_);
534}
535
536MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
537
538void 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
572void 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
667void 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
678void MessageOneofFieldGenerator::GenerateMessageClearingCode(
679 io::Printer* printer) const {
680 GenerateClearingCode(printer);
681}
682
683void MessageOneofFieldGenerator::GenerateSwappingCode(
684 io::Printer* printer) const {
685 // Don't print any swapping code. Swapping the union will swap this field.
686}
687
688void MessageOneofFieldGenerator::GenerateDestructorCode(
689 io::Printer* printer) const {
690 // We inherit from MessageFieldGenerator, so we need to override the default
691 // behavior.
692}
693
694void 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
700void 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
713RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
714 const FieldDescriptor* descriptor, const Options& options,
715 MessageSCCAnalyzer* scc_analyzer)
716 : FieldGenerator(descriptor, options),
717 implicit_weak_field_(
718 IsImplicitWeakField(field: descriptor, options, scc_analyzer)),
719 has_required_fields_(
720 scc_analyzer->HasRequiredFields(descriptor: descriptor->message_type())) {
721 SetMessageVariables(descriptor, options, implicit_weak: implicit_weak_field_, variables: &variables_);
722}
723
724RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
725
726void 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
736void 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
775void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
776 io::Printer* printer) const {
777 Formatter format(printer, variables_);
778 format.Set(key: "weak", value: 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
838void 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
846void 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
854void 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
862void RepeatedMessageFieldGenerator::GenerateConstructorCode(
863 io::Printer* printer) const {
864 // Not needed for repeated fields.
865}
866
867void 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
879void 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
924void 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
937void 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