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 | |
43 | namespace google { |
44 | namespace protobuf { |
45 | namespace compiler { |
46 | namespace cpp { |
47 | |
48 | namespace { |
49 | std::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 | |
59 | void 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 | |
92 | MessageFieldGenerator::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 | |
103 | MessageFieldGenerator::~MessageFieldGenerator() {} |
104 | |
105 | void 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 | |
114 | void 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 | |
160 | void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( |
161 | io::Printer* printer) const {} |
162 | |
163 | 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 | "$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 | |
310 | void 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 | |
324 | void 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 | |
375 | void 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 | |
392 | void 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 | |
412 | void 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 | |
427 | void 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 | |
434 | void 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 | |
453 | void 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 | |
464 | void 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 | |
483 | void 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 | |
493 | void 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 | |
505 | void MessageFieldGenerator::GenerateConstexprAggregateInitializer( |
506 | io::Printer* printer) const { |
507 | Formatter format(printer, variables_); |
508 | format("/*decltype($field$)*/nullptr" ); |
509 | } |
510 | |
511 | void MessageFieldGenerator::GenerateCopyAggregateInitializer( |
512 | io::Printer* printer) const { |
513 | Formatter format(printer, variables_); |
514 | format("decltype($field$){nullptr}" ); |
515 | } |
516 | |
517 | void 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 | |
529 | MessageOneofFieldGenerator::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 | |
536 | MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {} |
537 | |
538 | void 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 | |
572 | void 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 | |
667 | void 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 | |
678 | void MessageOneofFieldGenerator::GenerateMessageClearingCode( |
679 | io::Printer* printer) const { |
680 | GenerateClearingCode(printer); |
681 | } |
682 | |
683 | void MessageOneofFieldGenerator::GenerateSwappingCode( |
684 | io::Printer* printer) const { |
685 | // Don't print any swapping code. Swapping the union will swap this field. |
686 | } |
687 | |
688 | void MessageOneofFieldGenerator::GenerateDestructorCode( |
689 | io::Printer* printer) const { |
690 | // We inherit from MessageFieldGenerator, so we need to override the default |
691 | // behavior. |
692 | } |
693 | |
694 | void 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 | |
700 | void 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 | |
713 | RepeatedMessageFieldGenerator::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 | |
724 | RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} |
725 | |
726 | void 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 | |
736 | void 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 | |
775 | void 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 | |
838 | void 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 | |
846 | void 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 | |
854 | void 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 | |
862 | void RepeatedMessageFieldGenerator::GenerateConstructorCode( |
863 | io::Printer* printer) const { |
864 | // Not needed for repeated fields. |
865 | } |
866 | |
867 | void 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 | |
879 | void 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 | |
924 | void 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 | |
937 | void 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 | |