Line data Source code
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 : #include <google/protobuf/stubs/strutil.h>
39 :
40 : namespace google {
41 : namespace protobuf {
42 : namespace compiler {
43 : namespace cpp {
44 :
45 : namespace {
46 :
47 2286 : void SetMessageVariables(const FieldDescriptor* descriptor,
48 : map<string, string>* variables,
49 : const Options& options) {
50 381 : SetCommonFieldVariables(descriptor, variables, options);
51 1143 : (*variables)["type"] = FieldMessageTypeName(descriptor);
52 762 : if (descriptor->options().weak() || !descriptor->containing_oneof()) {
53 1348 : (*variables)["non_null_ptr_to_name"] =
54 674 : StrCat("this->", (*variables)["name"], "_");
55 : }
56 1524 : (*variables)["stream_writer"] = (*variables)["declared_type"] +
57 381 : (HasFastArraySerialization(descriptor->message_type()->file()) ?
58 : "MaybeToArray" :
59 : "");
60 : // NOTE: Escaped here to unblock proto1->proto2 migration.
61 : // TODO(liujisi): Extend this to apply for other conflicting methods.
62 1905 : (*variables)["release_name"] =
63 : SafeFunctionName(descriptor->containing_type(),
64 : descriptor, "release_");
65 762 : (*variables)["full_name"] = descriptor->full_name();
66 381 : if (options.proto_h && IsFieldDependent(descriptor)) {
67 0 : (*variables)["dependent_type"] = "T::" + DependentTypeName(descriptor);
68 0 : (*variables)["dependent_typename"] =
69 0 : "typename T::" + DependentTypeName(descriptor);
70 : } else {
71 1143 : (*variables)["dependent_type"] = FieldMessageTypeName(descriptor);
72 1143 : (*variables)["dependent_typename"] = FieldMessageTypeName(descriptor);
73 : }
74 381 : }
75 :
76 : } // namespace
77 :
78 : // ===================================================================
79 :
80 287 : MessageFieldGenerator::
81 : MessageFieldGenerator(const FieldDescriptor* descriptor,
82 : const Options& options)
83 : : descriptor_(descriptor),
84 574 : dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
85 287 : SetMessageVariables(descriptor, &variables_, options);
86 287 : }
87 :
88 817 : MessageFieldGenerator::~MessageFieldGenerator() {}
89 :
90 296 : void MessageFieldGenerator::
91 : GeneratePrivateMembers(io::Printer* printer) const {
92 296 : printer->Print(variables_, "$type$* $name$_;\n");
93 296 : }
94 :
95 209 : void MessageFieldGenerator::
96 : GenerateGetterDeclaration(io::Printer* printer) const {
97 : printer->Print(variables_,
98 209 : "const $type$& $name$() const$deprecation$;\n");
99 209 : }
100 :
101 0 : void MessageFieldGenerator::
102 : GenerateDependentAccessorDeclarations(io::Printer* printer) const {
103 0 : if (!dependent_field_) {
104 0 : return;
105 : }
106 : // Arena manipulation code is out-of-line in the derived message class.
107 : printer->Print(variables_,
108 : "$type$* mutable_$name$()$deprecation$;\n"
109 : "$type$* $release_name$()$deprecation$;\n"
110 0 : "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
111 : }
112 :
113 253 : void MessageFieldGenerator::
114 : GenerateAccessorDeclarations(io::Printer* printer) const {
115 555 : if (SupportsArenas(descriptor_)) {
116 : printer->Print(variables_,
117 : "private:\n"
118 49 : "void _slow_mutable_$name$()$deprecation$;\n");
119 147 : if (SupportsArenas(descriptor_->message_type())) {
120 : printer->Print(variables_,
121 : "void _slow_set_allocated_$name$(\n"
122 47 : " ::google::protobuf::Arena* message_arena, $type$** $name$)$deprecation$;\n");
123 : }
124 : printer->Print(variables_,
125 : "$type$* _slow_$release_name$()$deprecation$;\n"
126 49 : "public:\n");
127 : }
128 253 : GenerateGetterDeclaration(printer);
129 253 : if (!dependent_field_) {
130 : printer->Print(variables_,
131 : "$type$* mutable_$name$()$deprecation$;\n"
132 : "$type$* $release_name$()$deprecation$;\n"
133 253 : "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
134 : }
135 506 : if (SupportsArenas(descriptor_)) {
136 : printer->Print(variables_,
137 : "$type$* unsafe_arena_release_$name$()$deprecation$;\n"
138 : "void unsafe_arena_set_allocated_$name$(\n"
139 49 : " $type$* $name$)$deprecation$;\n");
140 : }
141 253 : }
142 :
143 209 : void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
144 : io::Printer* printer) const {
145 500 : if (SupportsArenas(descriptor_)) {
146 : printer->Print(variables_,
147 41 : "void $classname$::_slow_mutable_$name$() {\n");
148 123 : if (SupportsArenas(descriptor_->message_type())) {
149 : printer->Print(variables_,
150 : " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
151 39 : " GetArenaNoVirtual());\n");
152 : } else {
153 : printer->Print(variables_,
154 : " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
155 2 : " GetArenaNoVirtual());\n");
156 : }
157 : printer->Print(variables_,
158 : "}\n"
159 : "$type$* $classname$::_slow_$release_name$() {\n"
160 : " if ($name$_ == NULL) {\n"
161 : " return NULL;\n"
162 : " } else {\n"
163 : " $type$* temp = new $type$;\n"
164 : " temp->MergeFrom(*$name$_);\n"
165 : " $name$_ = NULL;\n"
166 : " return temp;\n"
167 : " }\n"
168 : "}\n"
169 : "$type$* $classname$::unsafe_arena_release_$name$() {\n"
170 : " $clear_hasbit$\n"
171 : " $type$* temp = $name$_;\n"
172 : " $name$_ = NULL;\n"
173 : " return temp;\n"
174 41 : "}\n");
175 123 : if (SupportsArenas(descriptor_->message_type())) {
176 : // NOTE: the same logic is mirrored in weak_message_field.cc. Any
177 : // arena-related semantics changes should be made in both places.
178 : printer->Print(variables_,
179 : "void $classname$::_slow_set_allocated_$name$(\n"
180 : " ::google::protobuf::Arena* message_arena, $type$** $name$) {\n"
181 : " if (message_arena != NULL && \n"
182 : " ::google::protobuf::Arena::GetArena(*$name$) == NULL) {\n"
183 : " message_arena->Own(*$name$);\n"
184 : " } else if (message_arena !=\n"
185 : " ::google::protobuf::Arena::GetArena(*$name$)) {\n"
186 : " $type$* new_$name$ = \n"
187 : " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
188 : " message_arena);\n"
189 : " new_$name$->CopyFrom(**$name$);\n"
190 : " *$name$ = new_$name$;\n"
191 : " }\n"
192 39 : "}\n");
193 : }
194 : printer->Print(variables_,
195 : "void $classname$::unsafe_arena_set_allocated_$name$(\n"
196 : " $type$* $name$) {\n"
197 : // If we're not on an arena, free whatever we were holding before.
198 : // (If we are on arena, we can just forget the earlier pointer.)
199 : " if (GetArenaNoVirtual() == NULL) {\n"
200 : " delete $name$_;\n"
201 : " }\n"
202 : " $name$_ = $name$;\n"
203 : " if ($name$) {\n"
204 : " $set_hasbit$\n"
205 : " } else {\n"
206 : " $clear_hasbit$\n"
207 : " }\n"
208 : " // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
209 : ":$full_name$)\n"
210 41 : "}\n");
211 : }
212 209 : }
213 :
214 0 : void MessageFieldGenerator::
215 : GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
216 0 : if (!dependent_field_) {
217 0 : return;
218 : }
219 :
220 0 : map<string, string> variables(variables_);
221 : // For the CRTP base class, all mutation methods are dependent, and so
222 : // they must be in the header.
223 0 : variables["dependent_classname"] =
224 0 : DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
225 0 : variables["this_message"] = DependentBaseDownCast();
226 0 : if (!variables["set_hasbit"].empty()) {
227 0 : variables["set_hasbit"] =
228 0 : variables["this_message"] + variables["set_hasbit"];
229 : }
230 0 : if (!variables["clear_hasbit"].empty()) {
231 0 : variables["clear_hasbit"] =
232 0 : variables["this_message"] + variables["clear_hasbit"];
233 : }
234 :
235 0 : if (SupportsArenas(descriptor_)) {
236 : printer->Print(variables,
237 : "template <class T>\n"
238 : "inline $type$* $dependent_classname$::mutable_$name$() {\n"
239 : " $set_hasbit$\n"
240 : " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
241 : " if ($name$_ == NULL) {\n"
242 : " $this_message$_slow_mutable_$name$();\n"
243 : " }\n"
244 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
245 : " return $name$_;\n"
246 : "}\n"
247 : "template <class T>\n"
248 : "inline $type$* $dependent_classname$::$release_name$() {\n"
249 : " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
250 : " $clear_hasbit$\n"
251 : " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
252 : " return $this_message$_slow_$release_name$();\n"
253 : " } else {\n"
254 : " $dependent_typename$* temp = $name$_;\n"
255 : " $name$_ = NULL;\n"
256 : " return temp;\n"
257 : " }\n"
258 : "}\n"
259 : "template <class T>\n"
260 : "inline void $dependent_classname$::"
261 : "set_allocated_$name$($type$* $name$) {\n"
262 : " ::google::protobuf::Arena* message_arena = $this_message$GetArenaNoVirtual();\n"
263 : " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
264 : " if (message_arena == NULL) {\n"
265 : " delete $name$_;\n"
266 : " }\n"
267 0 : " if ($name$ != NULL) {\n");
268 0 : if (SupportsArenas(descriptor_->message_type())) {
269 : // If we're on an arena and the incoming message is not, simply Own() it
270 : // rather than copy to the arena -- either way we need a heap dealloc,
271 : // so we might as well defer it. Otherwise, if incoming message is on a
272 : // different ownership domain (specific arena, or the heap) than we are,
273 : // copy to our arena (or heap, as the case may be).
274 : printer->Print(variables,
275 : " $this_message$_slow_set_allocated_$name$(message_arena, "
276 0 : "&$name$);\n");
277 : } else {
278 : printer->Print(variables,
279 : " if (message_arena != NULL) {\n"
280 : " message_arena->Own($name$);\n"
281 0 : " }\n");
282 : }
283 : printer->Print(variables,
284 : " }\n"
285 : " $name$_ = $name$;\n"
286 : " if ($name$) {\n"
287 : " $set_hasbit$\n"
288 : " } else {\n"
289 : " $clear_hasbit$\n"
290 : " }\n"
291 : // TODO(dlj): move insertion points to message class.
292 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
293 0 : "}\n");
294 : } else {
295 : printer->Print(variables,
296 : "template <class T>\n"
297 : "inline $type$* $dependent_classname$::mutable_$name$() {\n"
298 : " $set_hasbit$\n"
299 : " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
300 : " if ($name$_ == NULL) {\n"
301 : " $name$_ = new $dependent_typename$;\n"
302 : " }\n"
303 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
304 : " return $name$_;\n"
305 : "}\n"
306 : "template <class T>\n"
307 : "inline $type$* $dependent_classname$::$release_name$() {\n"
308 : " $clear_hasbit$\n"
309 : " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
310 : " $dependent_typename$* temp = $name$_;\n"
311 : " $name$_ = NULL;\n"
312 : " return temp;\n"
313 : "}\n"
314 : "template <class T>\n"
315 : "inline void $dependent_classname$::"
316 : "set_allocated_$name$($type$* $name$) {\n"
317 : " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
318 0 : " delete $name$_;\n");
319 :
320 0 : if (SupportsArenas(descriptor_->message_type())) {
321 : printer->Print(variables,
322 : " if ($name$ != NULL && static_cast< $dependent_typename$* >($name$)"
323 : "->GetArena() != NULL) {\n"
324 : " $dependent_typename$* new_$name$ = new $dependent_typename$;\n"
325 : " new_$name$->CopyFrom(*$name$);\n"
326 : " $name$ = new_$name$;\n"
327 0 : " }\n");
328 : }
329 :
330 : printer->Print(variables,
331 : " $name$_ = $name$;\n"
332 : " if ($name$) {\n"
333 : " $set_hasbit$\n"
334 : " } else {\n"
335 : " $clear_hasbit$\n"
336 : " }\n"
337 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
338 0 : "}\n");
339 : }
340 : }
341 :
342 418 : void MessageFieldGenerator::
343 : GenerateInlineAccessorDefinitions(io::Printer* printer,
344 : bool is_inline) const {
345 418 : map<string, string> variables(variables_);
346 836 : variables["inline"] = is_inline ? "inline " : "";
347 : printer->Print(variables,
348 : "$inline$const $type$& $classname$::$name$() const {\n"
349 418 : " // @@protoc_insertion_point(field_get:$full_name$)\n");
350 :
351 : PrintHandlingOptionalStaticInitializers(
352 : variables, descriptor_->file(), printer,
353 : // With static initializers.
354 : " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
355 : // Without.
356 836 : " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
357 418 : printer->Print(variables, "}\n");
358 :
359 418 : if (dependent_field_) {
360 418 : return;
361 : }
362 :
363 836 : if (SupportsArenas(descriptor_)) {
364 : printer->Print(variables,
365 : "$inline$"
366 : "$type$* $classname$::mutable_$name$() {\n"
367 : " $set_hasbit$\n"
368 : " if ($name$_ == NULL) {\n"
369 : " _slow_mutable_$name$();\n"
370 : " }\n"
371 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
372 : " return $name$_;\n"
373 : "}\n"
374 : "$inline$"
375 : "$type$* $classname$::$release_name$() {\n"
376 : " $clear_hasbit$\n"
377 : " if (GetArenaNoVirtual() != NULL) {\n"
378 : " return _slow_$release_name$();\n"
379 : " } else {\n"
380 : " $type$* temp = $name$_;\n"
381 : " $name$_ = NULL;\n"
382 : " return temp;\n"
383 : " }\n"
384 : "}\n"
385 : "$inline$ "
386 : "void $classname$::set_allocated_$name$($type$* $name$) {\n"
387 : " ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n"
388 : " if (message_arena == NULL) {\n"
389 : " delete $name$_;\n"
390 : " }\n"
391 82 : " if ($name$ != NULL) {\n");
392 246 : if (SupportsArenas(descriptor_->message_type())) {
393 : // If we're on an arena and the incoming message is not, simply Own() it
394 : // rather than copy to the arena -- either way we need a heap dealloc,
395 : // so we might as well defer it. Otherwise, if incoming message is on a
396 : // different ownership domain (specific arena, or the heap) than we are,
397 : // copy to our arena (or heap, as the case may be).
398 : printer->Print(variables,
399 78 : " _slow_set_allocated_$name$(message_arena, &$name$);\n");
400 : } else {
401 : printer->Print(variables,
402 : " if (message_arena != NULL) {\n"
403 : " message_arena->Own($name$);\n"
404 4 : " }\n");
405 : }
406 : printer->Print(variables,
407 : " }\n"
408 : " $name$_ = $name$;\n"
409 : " if ($name$) {\n"
410 : " $set_hasbit$\n"
411 : " } else {\n"
412 : " $clear_hasbit$\n"
413 : " }\n"
414 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
415 82 : "}\n");
416 : } else {
417 : printer->Print(variables,
418 : "$inline$"
419 : "$type$* $classname$::mutable_$name$() {\n"
420 : " $set_hasbit$\n"
421 : " if ($name$_ == NULL) {\n"
422 : " $name$_ = new $type$;\n"
423 : " }\n"
424 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
425 : " return $name$_;\n"
426 : "}\n"
427 : "$inline$"
428 : "$type$* $classname$::$release_name$() {\n"
429 : " $clear_hasbit$\n"
430 : " $type$* temp = $name$_;\n"
431 : " $name$_ = NULL;\n"
432 : " return temp;\n"
433 : "}\n"
434 : "$inline$"
435 : "void $classname$::set_allocated_$name$($type$* $name$) {\n"
436 336 : " delete $name$_;\n");
437 :
438 1008 : if (SupportsArenas(descriptor_->message_type())) {
439 : printer->Print(variables,
440 : " if ($name$ != NULL && $name$->GetArena() != NULL) {\n"
441 : " $type$* new_$name$ = new $type$;\n"
442 : " new_$name$->CopyFrom(*$name$);\n"
443 : " $name$ = new_$name$;\n"
444 12 : " }\n");
445 : }
446 :
447 : printer->Print(variables,
448 : " $name$_ = $name$;\n"
449 : " if ($name$) {\n"
450 : " $set_hasbit$\n"
451 : " } else {\n"
452 : " $clear_hasbit$\n"
453 : " }\n"
454 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
455 336 : "}\n");
456 : }
457 : }
458 :
459 625 : void MessageFieldGenerator::
460 : GenerateClearingCode(io::Printer* printer) const {
461 625 : map<string, string> variables(variables_);
462 1875 : variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
463 1250 : if (!HasFieldPresence(descriptor_->file())) {
464 : // If we don't have has-bits, message presence is indicated only by ptr !=
465 : // NULL. Thus on clear, we need to delete the object.
466 : printer->Print(variables,
467 : "if ($this_message$GetArenaNoVirtual() == NULL && "
468 : "$this_message$$name$_ != NULL) delete $this_message$$name$_;\n"
469 420 : "$this_message$$name$_ = NULL;\n");
470 : } else {
471 : printer->Print(variables,
472 : "if ($this_message$$name$_ != NULL) $this_message$$name$_->"
473 205 : "$dependent_type$::Clear();\n");
474 : }
475 625 : }
476 :
477 251 : void MessageFieldGenerator::
478 : GenerateMergingCode(io::Printer* printer) const {
479 : printer->Print(variables_,
480 251 : "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
481 251 : }
482 :
483 207 : void MessageFieldGenerator::
484 : GenerateSwappingCode(io::Printer* printer) const {
485 207 : printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
486 207 : }
487 :
488 209 : void MessageFieldGenerator::
489 : GenerateConstructorCode(io::Printer* printer) const {
490 209 : printer->Print(variables_, "$name$_ = NULL;\n");
491 209 : }
492 :
493 251 : void MessageFieldGenerator::
494 : GenerateMergeFromCodedStream(io::Printer* printer) const {
495 251 : if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
496 : printer->Print(variables_,
497 : "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
498 239 : " input, mutable_$name$()));\n");
499 : } else {
500 : printer->Print(variables_,
501 : "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
502 12 : " $number$, input, mutable_$name$()));\n");
503 : }
504 251 : }
505 :
506 251 : void MessageFieldGenerator::
507 : GenerateSerializeWithCachedSizes(io::Printer* printer) const {
508 : printer->Print(variables_,
509 : "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
510 251 : " $number$, *$non_null_ptr_to_name$, output);\n");
511 251 : }
512 :
513 236 : void MessageFieldGenerator::
514 : GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
515 : printer->Print(variables_,
516 : "target = ::google::protobuf::internal::WireFormatLite::\n"
517 : " Write$declared_type$NoVirtualToArray(\n"
518 236 : " $number$, *$non_null_ptr_to_name$, target);\n");
519 236 : }
520 :
521 251 : void MessageFieldGenerator::
522 : GenerateByteSize(io::Printer* printer) const {
523 : printer->Print(variables_,
524 : "total_size += $tag_size$ +\n"
525 : " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
526 251 : " *$non_null_ptr_to_name$);\n");
527 251 : }
528 :
529 : // ===================================================================
530 :
531 44 : MessageOneofFieldGenerator::
532 : MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
533 : const Options& options)
534 : : MessageFieldGenerator(descriptor, options),
535 44 : dependent_base_(options.proto_h) {
536 44 : SetCommonOneofFieldVariables(descriptor, &variables_);
537 44 : }
538 :
539 88 : MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
540 :
541 :
542 0 : void MessageOneofFieldGenerator::
543 : GenerateDependentAccessorDeclarations(io::Printer* printer) const {
544 : // Oneof field getters must be dependent as they call default_instance().
545 : // Otherwise, the logic is the same as MessageFields.
546 0 : if (!dependent_field_) {
547 0 : return;
548 : }
549 : printer->Print(variables_,
550 0 : "const $type$& $name$() const$deprecation$;\n");
551 0 : MessageFieldGenerator::GenerateDependentAccessorDeclarations(printer);
552 : }
553 :
554 44 : void MessageOneofFieldGenerator::
555 : GenerateGetterDeclaration(io::Printer* printer) const {
556 : // Oneof field getters must be dependent as they call default_instance().
557 : // Unlike MessageField, this means there is no (non-dependent) getter to
558 : // generate.
559 44 : if (dependent_field_) {
560 44 : return;
561 : }
562 : printer->Print(variables_,
563 44 : "const $type$& $name$() const$deprecation$;\n");
564 : }
565 :
566 0 : void MessageOneofFieldGenerator::
567 : GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
568 : // For the CRTP base class, all mutation methods are dependent, and so
569 : // they must be in the header.
570 0 : if (!dependent_base_) {
571 0 : return;
572 : }
573 0 : map<string, string> variables(variables_);
574 0 : variables["inline"] = "inline ";
575 0 : variables["dependent_classname"] =
576 0 : DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
577 0 : variables["this_message"] = "reinterpret_cast<T*>(this)->";
578 : // Const message access is needed for the dependent getter.
579 0 : variables["this_const_message"] = "reinterpret_cast<const T*>(this)->";
580 0 : variables["tmpl"] = "template <class T>\n";
581 0 : variables["field_member"] = variables["this_message"] +
582 0 : variables["oneof_prefix"] + variables["name"] +
583 : "_";
584 0 : InternalGenerateInlineAccessorDefinitions(variables, printer);
585 : }
586 :
587 88 : void MessageOneofFieldGenerator::
588 : GenerateInlineAccessorDefinitions(io::Printer* printer,
589 : bool is_inline) const {
590 88 : if (dependent_base_) {
591 0 : return;
592 : }
593 88 : map<string, string> variables(variables_);
594 176 : variables["inline"] = is_inline ? "inline " : "";
595 264 : variables["dependent_classname"] = variables["classname"];
596 176 : variables["this_message"] = "";
597 176 : variables["this_const_message"] = "";
598 176 : variables["tmpl"] = "";
599 176 : variables["field_member"] =
600 440 : variables["oneof_prefix"] + variables["name"] + "_";
601 264 : variables["dependent_type"] = variables["type"];
602 88 : InternalGenerateInlineAccessorDefinitions(variables, printer);
603 : }
604 :
605 44 : void MessageOneofFieldGenerator::
606 : GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
607 44 : map<string, string> variables(variables_);
608 88 : variables["field_member"] =
609 220 : variables["oneof_prefix"] + variables["name"] + "_";
610 :
611 : //printer->Print(variables,
612 44 : }
613 :
614 88 : void MessageOneofFieldGenerator::
615 : InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables,
616 : io::Printer* printer) const {
617 : printer->Print(variables,
618 : "$tmpl$"
619 : "$inline$ "
620 : "const $type$& $dependent_classname$::$name$() const {\n"
621 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
622 : " return $this_const_message$has_$name$()\n"
623 : " ? *$this_const_message$$oneof_prefix$$name$_\n"
624 : " : $dependent_type$::default_instance();\n"
625 88 : "}\n");
626 :
627 280 : if (SupportsArenas(descriptor_)) {
628 : printer->Print(variables,
629 : "$tmpl$"
630 : "$inline$"
631 : "$type$* $dependent_classname$::mutable_$name$() {\n"
632 : " if (!$this_message$has_$name$()) {\n"
633 : " $this_message$clear_$oneof_name$();\n"
634 16 : " $this_message$set_has_$name$();\n");
635 48 : if (SupportsArenas(descriptor_->message_type())) {
636 : printer->Print(variables,
637 : " $field_member$ = \n"
638 : " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n"
639 16 : " $this_message$GetArenaNoVirtual());\n");
640 : } else {
641 : printer->Print(variables,
642 : " $this_message$$oneof_prefix$$name$_ = \n"
643 : " ::google::protobuf::Arena::Create< $dependent_typename$ >(\n"
644 0 : " $this_message$GetArenaNoVirtual());\n");
645 : }
646 : printer->Print(variables,
647 : " }\n"
648 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
649 : " return $field_member$;\n"
650 : "}\n"
651 : "$tmpl$"
652 : "$inline$"
653 : "$type$* $dependent_classname$::$release_name$() {\n"
654 : " if ($this_message$has_$name$()) {\n"
655 : " $this_message$clear_has_$oneof_name$();\n"
656 : " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
657 : // N.B.: safe to use the underlying field pointer here because we are sure
658 : // that it is non-NULL (because has_$name$() returned true).
659 : " $dependent_typename$* temp = new $dependent_typename$;\n"
660 : " temp->MergeFrom(*$field_member$);\n"
661 : " $field_member$ = NULL;\n"
662 : " return temp;\n"
663 : " } else {\n"
664 : " $dependent_typename$* temp = $field_member$;\n"
665 : " $field_member$ = NULL;\n"
666 : " return temp;\n"
667 : " }\n"
668 : " } else {\n"
669 : " return NULL;\n"
670 : " }\n"
671 : "}\n"
672 : "$tmpl$"
673 : "$inline$"
674 : "void $dependent_classname$::"
675 : "set_allocated_$name$($type$* $name$) {\n"
676 : " $this_message$clear_$oneof_name$();\n"
677 16 : " if ($name$) {\n");
678 :
679 48 : if (SupportsArenas(descriptor_->message_type())) {
680 : printer->Print(variables,
681 : // If incoming message is on the heap and we are on an arena, just Own()
682 : // it (see above). If it's on a different arena than we are or one of us
683 : // is on the heap, we make a copy to our arena/heap.
684 : " if ($this_message$GetArenaNoVirtual() != NULL &&\n"
685 : " ::google::protobuf::Arena::GetArena($name$) == NULL) {\n"
686 : " $this_message$GetArenaNoVirtual()->Own($name$);\n"
687 : " } else if ($this_message$GetArenaNoVirtual() !=\n"
688 : " ::google::protobuf::Arena::GetArena($name$)) {\n"
689 : " $dependent_typename$* new_$name$ = \n"
690 : " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n"
691 : " $this_message$GetArenaNoVirtual());\n"
692 : " new_$name$->CopyFrom(*$name$);\n"
693 : " $name$ = new_$name$;\n"
694 16 : " }\n");
695 : } else {
696 : printer->Print(variables,
697 : " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
698 : " $this_message$GetArenaNoVirtual()->Own($name$);\n"
699 0 : " }\n");
700 : }
701 :
702 : printer->Print(variables,
703 : " $this_message$set_has_$name$();\n"
704 : " $field_member$ = $name$;\n"
705 : " }\n"
706 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
707 : "}\n"
708 : "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
709 : " if (has_$name$()) {\n"
710 : " clear_has_$oneof_name$();\n"
711 : " $type$* temp = $oneof_prefix$$name$_;\n"
712 : " $oneof_prefix$$name$_ = NULL;\n"
713 : " return temp;\n"
714 : " } else {\n"
715 : " return NULL;\n"
716 : " }\n"
717 : "}\n"
718 : "$inline$ void $classname$::unsafe_arena_set_allocated_$name$"
719 : "($type$* $name$) {\n"
720 : // We rely on the oneof clear method to free the earlier contents of this
721 : // oneof. We can directly use the pointer we're given to set the new
722 : // value.
723 : " clear_$oneof_name$();\n"
724 : " if ($name$) {\n"
725 : " set_has_$name$();\n"
726 : " $oneof_prefix$$name$_ = $name$;\n"
727 : " }\n"
728 : " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
729 : "$full_name$)\n"
730 16 : "}\n");
731 : } else {
732 : printer->Print(variables,
733 : "$tmpl$"
734 : "$inline$"
735 : "$type$* $dependent_classname$::mutable_$name$() {\n"
736 : " if (!$this_message$has_$name$()) {\n"
737 : " $this_message$clear_$oneof_name$();\n"
738 : " $this_message$set_has_$name$();\n"
739 : " $field_member$ = new $dependent_typename$;\n"
740 : " }\n"
741 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
742 : " return $field_member$;\n"
743 : "}\n"
744 : "$tmpl$"
745 : "$inline$"
746 : "$type$* $dependent_classname$::$release_name$() {\n"
747 : " if ($this_message$has_$name$()) {\n"
748 : " $this_message$clear_has_$oneof_name$();\n"
749 : " $dependent_typename$* temp = $field_member$;\n"
750 : " $field_member$ = NULL;\n"
751 : " return temp;\n"
752 : " } else {\n"
753 : " return NULL;\n"
754 : " }\n"
755 : "}\n"
756 : "$tmpl$"
757 : "$inline$"
758 : "void $dependent_classname$::"
759 : "set_allocated_$name$($type$* $name$) {\n"
760 : " $this_message$clear_$oneof_name$();\n"
761 72 : " if ($name$) {\n");
762 216 : if (SupportsArenas(descriptor_->message_type())) {
763 : printer->Print(variables,
764 : " if (static_cast< $dependent_typename$*>($name$)->"
765 : "GetArena() != NULL) {\n"
766 : " $dependent_typename$* new_$name$ = new $dependent_typename$;\n"
767 : " new_$name$->CopyFrom(*$name$);\n"
768 : " $name$ = new_$name$;\n"
769 0 : " }\n");
770 : }
771 : printer->Print(variables,
772 : " $this_message$set_has_$name$();\n"
773 : " $field_member$ = $name$;\n"
774 : " }\n"
775 : " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
776 72 : "}\n");
777 : }
778 88 : }
779 :
780 132 : void MessageOneofFieldGenerator::
781 : GenerateClearingCode(io::Printer* printer) const {
782 132 : map<string, string> variables(variables_);
783 396 : variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
784 264 : if (SupportsArenas(descriptor_)) {
785 : printer->Print(variables,
786 : "if ($this_message$GetArenaNoVirtual() == NULL) {\n"
787 : " delete $this_message$$oneof_prefix$$name$_;\n"
788 24 : "}\n");
789 : } else {
790 : printer->Print(variables,
791 108 : "delete $this_message$$oneof_prefix$$name$_;\n");
792 : }
793 132 : }
794 :
795 44 : void MessageOneofFieldGenerator::
796 : GenerateSwappingCode(io::Printer* printer) const {
797 : // Don't print any swapping code. Swapping the union will swap this field.
798 44 : }
799 :
800 0 : void MessageOneofFieldGenerator::
801 : GenerateConstructorCode(io::Printer* printer) const {
802 : // Don't print any constructor code. The field is in a union. We allocate
803 : // space only when this field is used.
804 0 : }
805 :
806 : // ===================================================================
807 :
808 94 : RepeatedMessageFieldGenerator::
809 : RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
810 : const Options& options)
811 : : descriptor_(descriptor),
812 94 : dependent_field_(options.proto_h && IsFieldDependent(descriptor)),
813 282 : dependent_getter_(dependent_field_ && options.safe_boundary_check) {
814 94 : SetMessageVariables(descriptor, &variables_, options);
815 94 : }
816 :
817 282 : RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
818 :
819 94 : void RepeatedMessageFieldGenerator::
820 : GeneratePrivateMembers(io::Printer* printer) const {
821 : printer->Print(variables_,
822 94 : "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
823 94 : }
824 :
825 94 : void RepeatedMessageFieldGenerator::
826 : InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const {
827 : printer->Print(variables_,
828 : "$type$* mutable_$name$(int index)$deprecation$;\n"
829 94 : "$type$* add_$name$()$deprecation$;\n");
830 94 : if (dependent_getter_) {
831 : printer->Print(variables_,
832 : "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
833 0 : " $name$() const$deprecation$;\n");
834 : }
835 : printer->Print(variables_,
836 : "::google::protobuf::RepeatedPtrField< $type$ >*\n"
837 94 : " mutable_$name$()$deprecation$;\n");
838 94 : }
839 :
840 0 : void RepeatedMessageFieldGenerator::
841 : GenerateDependentAccessorDeclarations(io::Printer* printer) const {
842 0 : if (dependent_getter_) {
843 : printer->Print(variables_,
844 0 : "const $type$& $name$(int index) const$deprecation$;\n");
845 : }
846 0 : if (dependent_field_) {
847 0 : InternalGenerateTypeDependentAccessorDeclarations(printer);
848 : }
849 0 : }
850 :
851 94 : void RepeatedMessageFieldGenerator::
852 : GenerateAccessorDeclarations(io::Printer* printer) const {
853 94 : if (!dependent_getter_) {
854 : printer->Print(variables_,
855 94 : "const $type$& $name$(int index) const$deprecation$;\n");
856 : }
857 94 : if (!dependent_field_) {
858 94 : InternalGenerateTypeDependentAccessorDeclarations(printer);
859 : }
860 94 : if (!dependent_getter_) {
861 : printer->Print(variables_,
862 : "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
863 94 : " $name$() const$deprecation$;\n");
864 : }
865 94 : }
866 :
867 0 : void RepeatedMessageFieldGenerator::
868 : GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
869 0 : if (!dependent_field_) {
870 0 : return;
871 : }
872 0 : map<string, string> variables(variables_);
873 : // For the CRTP base class, all mutation methods are dependent, and so
874 : // they must be in the header.
875 0 : variables["dependent_classname"] =
876 0 : DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
877 0 : variables["this_message"] = DependentBaseDownCast();
878 0 : variables["this_const_message"] = DependentBaseConstDownCast();
879 :
880 0 : if (dependent_getter_) {
881 : printer->Print(variables,
882 : "template <class T>\n"
883 : "inline const $type$& $dependent_classname$::$name$(int index) const {\n"
884 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
885 : " return $this_const_message$$name$_.$cppget$(index);\n"
886 0 : "}\n");
887 : }
888 :
889 : // Generate per-element accessors:
890 : printer->Print(variables,
891 : "template <class T>\n"
892 : "inline $type$* $dependent_classname$::mutable_$name$(int index) {\n"
893 : // TODO(dlj): move insertion points
894 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
895 : " return $this_message$$name$_.Mutable(index);\n"
896 : "}\n"
897 : "template <class T>\n"
898 : "inline $type$* $dependent_classname$::add_$name$() {\n"
899 : " // @@protoc_insertion_point(field_add:$full_name$)\n"
900 : " return $this_message$$name$_.Add();\n"
901 0 : "}\n");
902 :
903 :
904 0 : if (dependent_getter_) {
905 : printer->Print(variables,
906 : "template <class T>\n"
907 : "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
908 : "$dependent_classname$::$name$() const {\n"
909 : " // @@protoc_insertion_point(field_list:$full_name$)\n"
910 : " return $this_const_message$$name$_;\n"
911 0 : "}\n");
912 : }
913 :
914 : // Generate mutable access to the entire list:
915 : printer->Print(variables,
916 : "template <class T>\n"
917 : "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
918 : "$dependent_classname$::mutable_$name$() {\n"
919 : " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
920 : " return &$this_message$$name$_;\n"
921 0 : "}\n");
922 : }
923 :
924 188 : void RepeatedMessageFieldGenerator::
925 : GenerateInlineAccessorDefinitions(io::Printer* printer,
926 : bool is_inline) const {
927 188 : map<string, string> variables(variables_);
928 376 : variables["inline"] = is_inline ? "inline " : "";
929 :
930 188 : if (!dependent_getter_) {
931 : printer->Print(variables,
932 : "$inline$"
933 : "const $type$& $classname$::$name$(int index) const {\n"
934 : " // @@protoc_insertion_point(field_get:$full_name$)\n"
935 : " return $name$_.$cppget$(index);\n"
936 188 : "}\n");
937 : }
938 :
939 188 : if (!dependent_field_) {
940 : printer->Print(variables,
941 : "$inline$"
942 : "$type$* $classname$::mutable_$name$(int index) {\n"
943 : // TODO(dlj): move insertion points
944 : " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
945 : " return $name$_.Mutable(index);\n"
946 : "}\n"
947 : "$inline$"
948 : "$type$* $classname$::add_$name$() {\n"
949 : " // @@protoc_insertion_point(field_add:$full_name$)\n"
950 : " return $name$_.Add();\n"
951 188 : "}\n");
952 : }
953 :
954 :
955 188 : if (!dependent_field_) {
956 : printer->Print(variables,
957 : "$inline$"
958 : "::google::protobuf::RepeatedPtrField< $type$ >*\n"
959 : "$classname$::mutable_$name$() {\n"
960 : " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
961 : " return &$name$_;\n"
962 188 : "}\n");
963 : }
964 188 : if (!dependent_getter_) {
965 : printer->Print(variables,
966 : "$inline$"
967 : "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
968 : "$classname$::$name$() const {\n"
969 : " // @@protoc_insertion_point(field_list:$full_name$)\n"
970 : " return $name$_;\n"
971 188 : "}\n");
972 : }
973 188 : }
974 :
975 282 : void RepeatedMessageFieldGenerator::
976 : GenerateClearingCode(io::Printer* printer) const {
977 282 : map<string, string> variables(variables_);
978 846 : variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
979 282 : printer->Print(variables, "$this_message$$name$_.Clear();\n");
980 282 : }
981 :
982 94 : void RepeatedMessageFieldGenerator::
983 : GenerateMergingCode(io::Printer* printer) const {
984 94 : printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
985 94 : }
986 :
987 94 : void RepeatedMessageFieldGenerator::
988 : GenerateSwappingCode(io::Printer* printer) const {
989 94 : printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n");
990 94 : }
991 :
992 94 : void RepeatedMessageFieldGenerator::
993 : GenerateConstructorCode(io::Printer* printer) const {
994 : // Not needed for repeated fields.
995 94 : }
996 :
997 94 : void RepeatedMessageFieldGenerator::
998 : GenerateMergeFromCodedStream(io::Printer* printer) const {
999 94 : if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
1000 : printer->Print(variables_,
1001 : "DO_(::google::protobuf::internal::WireFormatLite::"
1002 : "ReadMessageNoVirtualNoRecursionDepth(\n"
1003 84 : " input, add_$name$()));\n");
1004 : } else {
1005 : printer->Print(variables_,
1006 : "DO_(::google::protobuf::internal::WireFormatLite::"
1007 : "ReadGroupNoVirtualNoRecursionDepth(\n"
1008 10 : " $number$, input, add_$name$()));\n");
1009 : }
1010 94 : }
1011 :
1012 94 : void RepeatedMessageFieldGenerator::
1013 : GenerateSerializeWithCachedSizes(io::Printer* printer) const {
1014 : printer->Print(variables_,
1015 : "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
1016 : " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
1017 : " $number$, this->$name$(i), output);\n"
1018 94 : "}\n");
1019 94 : }
1020 :
1021 80 : void RepeatedMessageFieldGenerator::
1022 : GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
1023 : printer->Print(variables_,
1024 : "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
1025 : " target = ::google::protobuf::internal::WireFormatLite::\n"
1026 : " Write$declared_type$NoVirtualToArray(\n"
1027 : " $number$, this->$name$(i), target);\n"
1028 80 : "}\n");
1029 80 : }
1030 :
1031 94 : void RepeatedMessageFieldGenerator::
1032 : GenerateByteSize(io::Printer* printer) const {
1033 : printer->Print(variables_,
1034 : "total_size += $tag_size$ * this->$name$_size();\n"
1035 : "for (int i = 0; i < this->$name$_size(); i++) {\n"
1036 : " total_size +=\n"
1037 : " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
1038 : " this->$name$(i));\n"
1039 94 : "}\n");
1040 94 : }
1041 :
1042 : } // namespace cpp
1043 : } // namespace compiler
1044 : } // namespace protobuf
1045 : } // namespace google
|