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