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