1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
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 <algorithm>
36 #include <google/protobuf/stubs/hash.h>
37 #include <map>
38 #include <vector>
39 #include <google/protobuf/compiler/cpp/cpp_message.h>
40 #include <google/protobuf/compiler/cpp/cpp_field.h>
41 #include <google/protobuf/compiler/cpp/cpp_enum.h>
42 #include <google/protobuf/compiler/cpp/cpp_extension.h>
43 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
44 #include <google/protobuf/stubs/strutil.h>
45 #include <google/protobuf/io/printer.h>
46 #include <google/protobuf/io/coded_stream.h>
47 #include <google/protobuf/wire_format.h>
48 #include <google/protobuf/descriptor.pb.h>
49
50 namespace google {
51 namespace protobuf {
52 namespace compiler {
53 namespace cpp {
54
55 using internal::WireFormat;
56 using internal::WireFormatLite;
57
58 namespace {
59
PrintFieldComment(io::Printer * printer,const FieldDescriptor * field)60 void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
61 // Print the field's proto-syntax definition as a comment. We don't want to
62 // print group bodies so we cut off after the first line.
63 string def = field->DebugString();
64 printer->Print("// $def$\n",
65 "def", def.substr(0, def.find_first_of('\n')));
66 }
67
68 struct FieldOrderingByNumber {
operator ()google::protobuf::compiler::cpp::__anon3b620e310111::FieldOrderingByNumber69 inline bool operator()(const FieldDescriptor* a,
70 const FieldDescriptor* b) const {
71 return a->number() < b->number();
72 }
73 };
74
75 const char* kWireTypeNames[] = {
76 "VARINT",
77 "FIXED64",
78 "LENGTH_DELIMITED",
79 "START_GROUP",
80 "END_GROUP",
81 "FIXED32",
82 };
83
84 // Sort the fields of the given Descriptor by number into a new[]'d array
85 // and return it.
SortFieldsByNumber(const Descriptor * descriptor)86 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
87 const FieldDescriptor** fields =
88 new const FieldDescriptor*[descriptor->field_count()];
89 for (int i = 0; i < descriptor->field_count(); i++) {
90 fields[i] = descriptor->field(i);
91 }
92 sort(fields, fields + descriptor->field_count(),
93 FieldOrderingByNumber());
94 return fields;
95 }
96
97 // Functor for sorting extension ranges by their "start" field number.
98 struct ExtensionRangeSorter {
operator ()google::protobuf::compiler::cpp::__anon3b620e310111::ExtensionRangeSorter99 bool operator()(const Descriptor::ExtensionRange* left,
100 const Descriptor::ExtensionRange* right) const {
101 return left->start < right->start;
102 }
103 };
104
105 // Returns true if the message type has any required fields. If it doesn't,
106 // we can optimize out calls to its IsInitialized() method.
107 //
108 // already_seen is used to avoid checking the same type multiple times
109 // (and also to protect against recursion).
HasRequiredFields(const Descriptor * type,hash_set<const Descriptor * > * already_seen)110 static bool HasRequiredFields(
111 const Descriptor* type,
112 hash_set<const Descriptor*>* already_seen) {
113 if (already_seen->count(type) > 0) {
114 // Since the first occurrence of a required field causes the whole
115 // function to return true, we can assume that if the type is already
116 // in the cache it didn't have any required fields.
117 return false;
118 }
119 already_seen->insert(type);
120
121 // If the type has extensions, an extension with message type could contain
122 // required fields, so we have to be conservative and assume such an
123 // extension exists.
124 if (type->extension_range_count() > 0) return true;
125
126 for (int i = 0; i < type->field_count(); i++) {
127 const FieldDescriptor* field = type->field(i);
128 if (field->is_required()) {
129 return true;
130 }
131 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
132 if (HasRequiredFields(field->message_type(), already_seen)) {
133 return true;
134 }
135 }
136 }
137
138 return false;
139 }
140
HasRequiredFields(const Descriptor * type)141 static bool HasRequiredFields(const Descriptor* type) {
142 hash_set<const Descriptor*> already_seen;
143 return HasRequiredFields(type, &already_seen);
144 }
145
146 }
147
148 // ===================================================================
149
MessageGenerator(const Descriptor * descriptor,const string & dllexport_decl)150 MessageGenerator::MessageGenerator(const Descriptor* descriptor,
151 const string& dllexport_decl)
152 : descriptor_(descriptor),
153 classname_(ClassName(descriptor, false)),
154 dllexport_decl_(dllexport_decl),
155 field_generators_(descriptor),
156 nested_generators_(new scoped_ptr<MessageGenerator>[
157 descriptor->nested_type_count()]),
158 enum_generators_(new scoped_ptr<EnumGenerator>[
159 descriptor->enum_type_count()]),
160 extension_generators_(new scoped_ptr<ExtensionGenerator>[
161 descriptor->extension_count()]) {
162
163 for (int i = 0; i < descriptor->nested_type_count(); i++) {
164 nested_generators_[i].reset(
165 new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
166 }
167
168 for (int i = 0; i < descriptor->enum_type_count(); i++) {
169 enum_generators_[i].reset(
170 new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
171 }
172
173 for (int i = 0; i < descriptor->extension_count(); i++) {
174 extension_generators_[i].reset(
175 new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
176 }
177 }
178
~MessageGenerator()179 MessageGenerator::~MessageGenerator() {}
180
181 void MessageGenerator::
GenerateForwardDeclaration(io::Printer * printer)182 GenerateForwardDeclaration(io::Printer* printer) {
183 printer->Print("class $classname$;\n",
184 "classname", classname_);
185
186 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
187 nested_generators_[i]->GenerateForwardDeclaration(printer);
188 }
189 }
190
191 void MessageGenerator::
GenerateEnumDefinitions(io::Printer * printer)192 GenerateEnumDefinitions(io::Printer* printer) {
193 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
194 nested_generators_[i]->GenerateEnumDefinitions(printer);
195 }
196
197 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
198 enum_generators_[i]->GenerateDefinition(printer);
199 }
200 }
201
202 void MessageGenerator::
GenerateGetEnumDescriptorSpecializations(io::Printer * printer)203 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
204 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
205 nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
206 }
207 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
208 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
209 }
210 }
211
212 void MessageGenerator::
GenerateFieldAccessorDeclarations(io::Printer * printer)213 GenerateFieldAccessorDeclarations(io::Printer* printer) {
214 for (int i = 0; i < descriptor_->field_count(); i++) {
215 const FieldDescriptor* field = descriptor_->field(i);
216
217 PrintFieldComment(printer, field);
218
219 map<string, string> vars;
220 SetCommonFieldVariables(field, &vars);
221 vars["constant_name"] = FieldConstantName(field);
222
223 if (field->is_repeated()) {
224 printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
225 } else {
226 printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
227 }
228
229 printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
230 printer->Print(vars, "static const int $constant_name$ = $number$;\n");
231
232 // Generate type-specific accessor declarations.
233 field_generators_.get(field).GenerateAccessorDeclarations(printer);
234
235 printer->Print("\n");
236 }
237
238 if (descriptor_->extension_range_count() > 0) {
239 // Generate accessors for extensions. We just call a macro located in
240 // extension_set.h since the accessors about 80 lines of static code.
241 printer->Print(
242 "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
243 "classname", classname_);
244 }
245 }
246
247 void MessageGenerator::
GenerateFieldAccessorDefinitions(io::Printer * printer)248 GenerateFieldAccessorDefinitions(io::Printer* printer) {
249 printer->Print("// $classname$\n\n", "classname", classname_);
250
251 for (int i = 0; i < descriptor_->field_count(); i++) {
252 const FieldDescriptor* field = descriptor_->field(i);
253
254 PrintFieldComment(printer, field);
255
256 map<string, string> vars;
257 SetCommonFieldVariables(field, &vars);
258
259 // Generate has_$name$() or $name$_size().
260 if (field->is_repeated()) {
261 printer->Print(vars,
262 "inline int $classname$::$name$_size() const {\n"
263 " return $name$_.size();\n"
264 "}\n");
265 } else {
266 // Singular field.
267 printer->Print(vars,
268 "inline bool $classname$::has_$name$() const {\n"
269 " return _has_bit($index$);\n"
270 "}\n");
271 }
272
273 // Generate clear_$name$()
274 printer->Print(vars,
275 "inline void $classname$::clear_$name$() {\n");
276
277 printer->Indent();
278 field_generators_.get(field).GenerateClearingCode(printer);
279 printer->Outdent();
280
281 if (!field->is_repeated()) {
282 printer->Print(vars, " _clear_bit($index$);\n");
283 }
284
285 printer->Print("}\n");
286
287 // Generate type-specific accessors.
288 field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
289
290 printer->Print("\n");
291 }
292 }
293
294 void MessageGenerator::
GenerateClassDefinition(io::Printer * printer)295 GenerateClassDefinition(io::Printer* printer) {
296 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
297 nested_generators_[i]->GenerateClassDefinition(printer);
298 printer->Print("\n");
299 printer->Print(kThinSeparator);
300 printer->Print("\n");
301 }
302
303 map<string, string> vars;
304 vars["classname"] = classname_;
305 vars["field_count"] = SimpleItoa(descriptor_->field_count());
306 if (dllexport_decl_.empty()) {
307 vars["dllexport"] = "";
308 } else {
309 vars["dllexport"] = dllexport_decl_ + " ";
310 }
311 vars["superclass"] = SuperClassName(descriptor_);
312
313 printer->Print(vars,
314 "class $dllexport$$classname$ : public $superclass$ {\n"
315 " public:\n");
316 printer->Indent();
317
318 printer->Print(vars,
319 "$classname$();\n"
320 "virtual ~$classname$();\n"
321 "\n"
322 "$classname$(const $classname$& from);\n"
323 "\n"
324 "inline $classname$& operator=(const $classname$& from) {\n"
325 " CopyFrom(from);\n"
326 " return *this;\n"
327 "}\n"
328 "\n");
329
330 if (HasUnknownFields(descriptor_->file())) {
331 printer->Print(
332 "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
333 " return _unknown_fields_;\n"
334 "}\n"
335 "\n"
336 "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
337 " return &_unknown_fields_;\n"
338 "}\n"
339 "\n");
340 }
341
342 // Only generate this member if it's not disabled.
343 if (HasDescriptorMethods(descriptor_->file()) &&
344 !descriptor_->options().no_standard_descriptor_accessor()) {
345 printer->Print(vars,
346 "static const ::google::protobuf::Descriptor* descriptor();\n");
347 }
348
349 printer->Print(vars,
350 "static const $classname$& default_instance();\n"
351 "\n");
352
353
354 printer->Print(vars,
355 "void Swap($classname$* other);\n"
356 "\n"
357 "// implements Message ----------------------------------------------\n"
358 "\n"
359 "$classname$* New() const;\n");
360
361 if (HasGeneratedMethods(descriptor_->file())) {
362 if (HasDescriptorMethods(descriptor_->file())) {
363 printer->Print(vars,
364 "void CopyFrom(const ::google::protobuf::Message& from);\n"
365 "void MergeFrom(const ::google::protobuf::Message& from);\n");
366 } else {
367 printer->Print(vars,
368 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
369 }
370
371 printer->Print(vars,
372 "void CopyFrom(const $classname$& from);\n"
373 "void MergeFrom(const $classname$& from);\n"
374 "void Clear();\n"
375 "bool IsInitialized() const;\n"
376 "\n"
377 "int ByteSize() const;\n"
378 "bool MergePartialFromCodedStream(\n"
379 " ::google::protobuf::io::CodedInputStream* input);\n"
380 "void SerializeWithCachedSizes(\n"
381 " ::google::protobuf::io::CodedOutputStream* output) const;\n");
382 if (HasFastArraySerialization(descriptor_->file())) {
383 printer->Print(
384 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
385 }
386 }
387
388 printer->Print(vars,
389 "int GetCachedSize() const { return _cached_size_; }\n"
390 "private:\n"
391 "void SharedCtor();\n"
392 "void SharedDtor();\n"
393 "void SetCachedSize(int size) const;\n"
394 "public:\n"
395 "\n");
396
397 if (HasDescriptorMethods(descriptor_->file())) {
398 printer->Print(
399 "::google::protobuf::Metadata GetMetadata() const;\n"
400 "\n");
401 } else {
402 printer->Print(
403 "::std::string GetTypeName() const;\n"
404 "\n");
405 }
406
407 printer->Print(
408 "// nested types ----------------------------------------------------\n"
409 "\n");
410
411 // Import all nested message classes into this class's scope with typedefs.
412 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
413 const Descriptor* nested_type = descriptor_->nested_type(i);
414 printer->Print("typedef $nested_full_name$ $nested_name$;\n",
415 "nested_name", nested_type->name(),
416 "nested_full_name", ClassName(nested_type, false));
417 }
418
419 if (descriptor_->nested_type_count() > 0) {
420 printer->Print("\n");
421 }
422
423 // Import all nested enums and their values into this class's scope with
424 // typedefs and constants.
425 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
426 enum_generators_[i]->GenerateSymbolImports(printer);
427 printer->Print("\n");
428 }
429
430 printer->Print(
431 "// accessors -------------------------------------------------------\n"
432 "\n");
433
434 // Generate accessor methods for all fields.
435 GenerateFieldAccessorDeclarations(printer);
436
437 // Declare extension identifiers.
438 for (int i = 0; i < descriptor_->extension_count(); i++) {
439 extension_generators_[i]->GenerateDeclaration(printer);
440 }
441
442
443 printer->Print(
444 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
445 "full_name", descriptor_->full_name());
446
447 // Generate private members for fields.
448 printer->Outdent();
449 printer->Print(" private:\n");
450 printer->Indent();
451
452 if (descriptor_->extension_range_count() > 0) {
453 printer->Print(
454 "::google::protobuf::internal::ExtensionSet _extensions_;\n");
455 }
456
457 if (HasUnknownFields(descriptor_->file())) {
458 printer->Print(
459 "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
460 }
461
462 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
463 printer->Print(
464 "mutable int _cached_size_;\n"
465 "\n");
466 for (int i = 0; i < descriptor_->field_count(); i++) {
467 field_generators_.get(descriptor_->field(i))
468 .GeneratePrivateMembers(printer);
469 }
470
471 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
472 // friends so that they can access private static variables like
473 // default_instance_ and reflection_.
474 printer->Print(
475 "friend void $dllexport_decl$ $adddescriptorsname$();\n",
476 "dllexport_decl", dllexport_decl_,
477 "adddescriptorsname",
478 GlobalAddDescriptorsName(descriptor_->file()->name()));
479 printer->Print(
480 "friend void $assigndescriptorsname$();\n"
481 "friend void $shutdownfilename$();\n"
482 "\n",
483 "assigndescriptorsname",
484 GlobalAssignDescriptorsName(descriptor_->file()->name()),
485 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
486
487 // Generate offsets and _has_bits_ boilerplate.
488 if (descriptor_->field_count() > 0) {
489 printer->Print(vars,
490 "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
491 } else {
492 // Zero-size arrays aren't technically allowed, and MSVC in particular
493 // doesn't like them. We still need to declare these arrays to make
494 // other code compile. Since this is an uncommon case, we'll just declare
495 // them with size 1 and waste some space. Oh well.
496 printer->Print(
497 "::google::protobuf::uint32 _has_bits_[1];\n");
498 }
499
500 printer->Print(
501 "\n"
502 "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n"
503 "inline bool _has_bit(int index) const {\n"
504 " return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n"
505 "}\n"
506 "inline void _set_bit(int index) {\n"
507 " _has_bits_[index / 32] |= (1u << (index % 32));\n"
508 "}\n"
509 "inline void _clear_bit(int index) {\n"
510 " _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
511 "}\n"
512 "\n"
513 "void InitAsDefaultInstance();\n"
514 "static $classname$* default_instance_;\n",
515 "classname", classname_);
516
517 printer->Outdent();
518 printer->Print(vars, "};");
519 }
520
521 void MessageGenerator::
GenerateInlineMethods(io::Printer * printer)522 GenerateInlineMethods(io::Printer* printer) {
523 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
524 nested_generators_[i]->GenerateInlineMethods(printer);
525 printer->Print(kThinSeparator);
526 printer->Print("\n");
527 }
528
529 GenerateFieldAccessorDefinitions(printer);
530 }
531
532 void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer * printer)533 GenerateDescriptorDeclarations(io::Printer* printer) {
534 printer->Print(
535 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
536 "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
537 " $name$_reflection_ = NULL;\n",
538 "name", classname_);
539
540 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
541 nested_generators_[i]->GenerateDescriptorDeclarations(printer);
542 }
543
544 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
545 printer->Print(
546 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
547 "name", ClassName(descriptor_->enum_type(i), false));
548 }
549 }
550
551 void MessageGenerator::
GenerateDescriptorInitializer(io::Printer * printer,int index)552 GenerateDescriptorInitializer(io::Printer* printer, int index) {
553 // TODO(kenton): Passing the index to this method is redundant; just use
554 // descriptor_->index() instead.
555 map<string, string> vars;
556 vars["classname"] = classname_;
557 vars["index"] = SimpleItoa(index);
558
559 // Obtain the descriptor from the parent's descriptor.
560 if (descriptor_->containing_type() == NULL) {
561 printer->Print(vars,
562 "$classname$_descriptor_ = file->message_type($index$);\n");
563 } else {
564 vars["parent"] = ClassName(descriptor_->containing_type(), false);
565 printer->Print(vars,
566 "$classname$_descriptor_ = "
567 "$parent$_descriptor_->nested_type($index$);\n");
568 }
569
570 // Generate the offsets.
571 GenerateOffsets(printer);
572
573 // Construct the reflection object.
574 printer->Print(vars,
575 "$classname$_reflection_ =\n"
576 " new ::google::protobuf::internal::GeneratedMessageReflection(\n"
577 " $classname$_descriptor_,\n"
578 " $classname$::default_instance_,\n"
579 " $classname$_offsets_,\n"
580 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
581 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
582 "$classname$, _unknown_fields_),\n");
583 if (descriptor_->extension_range_count() > 0) {
584 printer->Print(vars,
585 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
586 "$classname$, _extensions_),\n");
587 } else {
588 // No extensions.
589 printer->Print(vars,
590 " -1,\n");
591 }
592 printer->Print(vars,
593 " ::google::protobuf::DescriptorPool::generated_pool(),\n"
594 " ::google::protobuf::MessageFactory::generated_factory(),\n"
595 " sizeof($classname$));\n");
596
597 // Handle nested types.
598 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
599 nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
600 }
601
602 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
603 enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
604 }
605 }
606
607 void MessageGenerator::
GenerateTypeRegistrations(io::Printer * printer)608 GenerateTypeRegistrations(io::Printer* printer) {
609 // Register this message type with the message factory.
610 printer->Print(
611 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
612 " $classname$_descriptor_, &$classname$::default_instance());\n",
613 "classname", classname_);
614
615 // Handle nested types.
616 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
617 nested_generators_[i]->GenerateTypeRegistrations(printer);
618 }
619 }
620
621 void MessageGenerator::
GenerateDefaultInstanceAllocator(io::Printer * printer)622 GenerateDefaultInstanceAllocator(io::Printer* printer) {
623 // Construct the default instance. We can't call InitAsDefaultInstance() yet
624 // because we need to make sure all default instances that this one might
625 // depend on are constructed first.
626 printer->Print(
627 "$classname$::default_instance_ = new $classname$();\n",
628 "classname", classname_);
629
630 // Handle nested types.
631 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
632 nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
633 }
634
635 }
636
637 void MessageGenerator::
GenerateDefaultInstanceInitializer(io::Printer * printer)638 GenerateDefaultInstanceInitializer(io::Printer* printer) {
639 printer->Print(
640 "$classname$::default_instance_->InitAsDefaultInstance();\n",
641 "classname", classname_);
642
643 // Register extensions.
644 for (int i = 0; i < descriptor_->extension_count(); i++) {
645 extension_generators_[i]->GenerateRegistration(printer);
646 }
647
648 // Handle nested types.
649 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
650 nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
651 }
652 }
653
654 void MessageGenerator::
GenerateShutdownCode(io::Printer * printer)655 GenerateShutdownCode(io::Printer* printer) {
656 printer->Print(
657 "delete $classname$::default_instance_;\n",
658 "classname", classname_);
659
660 if (HasDescriptorMethods(descriptor_->file())) {
661 printer->Print(
662 "delete $classname$_reflection_;\n",
663 "classname", classname_);
664 }
665
666 // Handle nested types.
667 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
668 nested_generators_[i]->GenerateShutdownCode(printer);
669 }
670 }
671
672 void MessageGenerator::
GenerateClassMethods(io::Printer * printer)673 GenerateClassMethods(io::Printer* printer) {
674 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
675 enum_generators_[i]->GenerateMethods(printer);
676 }
677
678 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
679 nested_generators_[i]->GenerateClassMethods(printer);
680 printer->Print("\n");
681 printer->Print(kThinSeparator);
682 printer->Print("\n");
683 }
684
685 // Generate non-inline field definitions.
686 for (int i = 0; i < descriptor_->field_count(); i++) {
687 field_generators_.get(descriptor_->field(i))
688 .GenerateNonInlineAccessorDefinitions(printer);
689 }
690
691 // Generate field number constants.
692 printer->Print("#ifndef _MSC_VER\n");
693 for (int i = 0; i < descriptor_->field_count(); i++) {
694 const FieldDescriptor *field = descriptor_->field(i);
695 printer->Print(
696 "const int $classname$::$constant_name$;\n",
697 "classname", ClassName(FieldScope(field), false),
698 "constant_name", FieldConstantName(field));
699 }
700 printer->Print(
701 "#endif // !_MSC_VER\n"
702 "\n");
703
704 // Define extension identifiers.
705 for (int i = 0; i < descriptor_->extension_count(); i++) {
706 extension_generators_[i]->GenerateDefinition(printer);
707 }
708
709 GenerateStructors(printer);
710 printer->Print("\n");
711
712 if (HasGeneratedMethods(descriptor_->file())) {
713 GenerateClear(printer);
714 printer->Print("\n");
715
716 GenerateMergeFromCodedStream(printer);
717 printer->Print("\n");
718
719 GenerateSerializeWithCachedSizes(printer);
720 printer->Print("\n");
721
722 if (HasFastArraySerialization(descriptor_->file())) {
723 GenerateSerializeWithCachedSizesToArray(printer);
724 printer->Print("\n");
725 }
726
727 GenerateByteSize(printer);
728 printer->Print("\n");
729
730 GenerateMergeFrom(printer);
731 printer->Print("\n");
732
733 GenerateCopyFrom(printer);
734 printer->Print("\n");
735
736 GenerateIsInitialized(printer);
737 printer->Print("\n");
738 }
739
740 GenerateSwap(printer);
741 printer->Print("\n");
742
743 if (HasDescriptorMethods(descriptor_->file())) {
744 printer->Print(
745 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
746 " protobuf_AssignDescriptorsOnce();\n"
747 " ::google::protobuf::Metadata metadata;\n"
748 " metadata.descriptor = $classname$_descriptor_;\n"
749 " metadata.reflection = $classname$_reflection_;\n"
750 " return metadata;\n"
751 "}\n"
752 "\n",
753 "classname", classname_);
754 } else {
755 printer->Print(
756 "::std::string $classname$::GetTypeName() const {\n"
757 " return \"$type_name$\";\n"
758 "}\n"
759 "\n",
760 "classname", classname_,
761 "type_name", descriptor_->full_name());
762 }
763
764 }
765
766 void MessageGenerator::
GenerateOffsets(io::Printer * printer)767 GenerateOffsets(io::Printer* printer) {
768 printer->Print(
769 "static const int $classname$_offsets_[$field_count$] = {\n",
770 "classname", classname_,
771 "field_count", SimpleItoa(max(1, descriptor_->field_count())));
772 printer->Indent();
773
774 for (int i = 0; i < descriptor_->field_count(); i++) {
775 const FieldDescriptor* field = descriptor_->field(i);
776 printer->Print(
777 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
778 "classname", classname_,
779 "name", FieldName(field));
780 }
781
782 printer->Outdent();
783 printer->Print("};\n");
784 }
785
786 void MessageGenerator::
GenerateSharedConstructorCode(io::Printer * printer)787 GenerateSharedConstructorCode(io::Printer* printer) {
788 printer->Print(
789 "void $classname$::SharedCtor() {\n",
790 "classname", classname_);
791 printer->Indent();
792
793 printer->Print(
794 "_cached_size_ = 0;\n");
795
796 for (int i = 0; i < descriptor_->field_count(); i++) {
797 field_generators_.get(descriptor_->field(i))
798 .GenerateConstructorCode(printer);
799 }
800
801 printer->Print(
802 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
803
804 printer->Outdent();
805 printer->Print("}\n\n");
806 }
807
808 void MessageGenerator::
GenerateSharedDestructorCode(io::Printer * printer)809 GenerateSharedDestructorCode(io::Printer* printer) {
810 printer->Print(
811 "void $classname$::SharedDtor() {\n",
812 "classname", classname_);
813 printer->Indent();
814 // Write the destructors for each field.
815 for (int i = 0; i < descriptor_->field_count(); i++) {
816 field_generators_.get(descriptor_->field(i))
817 .GenerateDestructorCode(printer);
818 }
819
820 printer->Print(
821 "if (this != default_instance_) {\n");
822
823 // We need to delete all embedded messages.
824 // TODO(kenton): If we make unset messages point at default instances
825 // instead of NULL, then it would make sense to move this code into
826 // MessageFieldGenerator::GenerateDestructorCode().
827 for (int i = 0; i < descriptor_->field_count(); i++) {
828 const FieldDescriptor* field = descriptor_->field(i);
829
830 if (!field->is_repeated() &&
831 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
832 printer->Print(" delete $name$_;\n",
833 "name", FieldName(field));
834 }
835 }
836
837 printer->Outdent();
838 printer->Print(
839 " }\n"
840 "}\n"
841 "\n");
842 }
843
844 void MessageGenerator::
GenerateStructors(io::Printer * printer)845 GenerateStructors(io::Printer* printer) {
846 string superclass = SuperClassName(descriptor_);
847
848 // Generate the default constructor.
849 printer->Print(
850 "$classname$::$classname$()\n"
851 " : $superclass$() {\n"
852 " SharedCtor();\n"
853 "}\n",
854 "classname", classname_,
855 "superclass", superclass);
856
857 printer->Print(
858 "\n"
859 "void $classname$::InitAsDefaultInstance() {\n",
860 "classname", classname_);
861
862 // The default instance needs all of its embedded message pointers
863 // cross-linked to other default instances. We can't do this initialization
864 // in the constructor because some other default instances may not have been
865 // constructed yet at that time.
866 // TODO(kenton): Maybe all message fields (even for non-default messages)
867 // should be initialized to point at default instances rather than NULL?
868 for (int i = 0; i < descriptor_->field_count(); i++) {
869 const FieldDescriptor* field = descriptor_->field(i);
870
871 if (!field->is_repeated() &&
872 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
873 printer->Print(
874 " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
875 "name", FieldName(field),
876 "type", FieldMessageTypeName(field));
877 }
878 }
879 printer->Print(
880 "}\n"
881 "\n");
882
883 // Generate the copy constructor.
884 printer->Print(
885 "$classname$::$classname$(const $classname$& from)\n"
886 " : $superclass$() {\n"
887 " SharedCtor();\n"
888 " MergeFrom(from);\n"
889 "}\n"
890 "\n",
891 "classname", classname_,
892 "superclass", superclass);
893
894 // Generate the shared constructor code.
895 GenerateSharedConstructorCode(printer);
896
897 // Generate the destructor.
898 printer->Print(
899 "$classname$::~$classname$() {\n"
900 " SharedDtor();\n"
901 "}\n"
902 "\n",
903 "classname", classname_);
904
905 // Generate the shared destructor code.
906 GenerateSharedDestructorCode(printer);
907
908 // Generate SetCachedSize.
909 printer->Print(
910 "void $classname$::SetCachedSize(int size) const {\n"
911 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
912 " _cached_size_ = size;\n"
913 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
914 "}\n",
915 "classname", classname_);
916
917 // Only generate this member if it's not disabled.
918 if (HasDescriptorMethods(descriptor_->file()) &&
919 !descriptor_->options().no_standard_descriptor_accessor()) {
920 printer->Print(
921 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
922 " protobuf_AssignDescriptorsOnce();\n"
923 " return $classname$_descriptor_;\n"
924 "}\n"
925 "\n",
926 "classname", classname_,
927 "adddescriptorsname",
928 GlobalAddDescriptorsName(descriptor_->file()->name()));
929 }
930
931 printer->Print(
932 "const $classname$& $classname$::default_instance() {\n"
933 " if (default_instance_ == NULL) $adddescriptorsname$();"
934 " return *default_instance_;\n"
935 "}\n"
936 "\n"
937 "$classname$* $classname$::default_instance_ = NULL;\n"
938 "\n"
939 "$classname$* $classname$::New() const {\n"
940 " return new $classname$;\n"
941 "}\n",
942 "classname", classname_,
943 "adddescriptorsname",
944 GlobalAddDescriptorsName(descriptor_->file()->name()));
945
946 }
947
948 void MessageGenerator::
GenerateClear(io::Printer * printer)949 GenerateClear(io::Printer* printer) {
950 printer->Print("void $classname$::Clear() {\n",
951 "classname", classname_);
952 printer->Indent();
953
954 int last_index = -1;
955
956 if (descriptor_->extension_range_count() > 0) {
957 printer->Print("_extensions_.Clear();\n");
958 }
959
960 for (int i = 0; i < descriptor_->field_count(); i++) {
961 const FieldDescriptor* field = descriptor_->field(i);
962
963 if (!field->is_repeated()) {
964 map<string, string> vars;
965 vars["index"] = SimpleItoa(field->index());
966
967 // We can use the fact that _has_bits_ is a giant bitfield to our
968 // advantage: We can check up to 32 bits at a time for equality to
969 // zero, and skip the whole range if so. This can improve the speed
970 // of Clear() for messages which contain a very large number of
971 // optional fields of which only a few are used at a time. Here,
972 // we've chosen to check 8 bits at a time rather than 32.
973 if (i / 8 != last_index / 8 || last_index < 0) {
974 if (last_index >= 0) {
975 printer->Outdent();
976 printer->Print("}\n");
977 }
978 printer->Print(vars,
979 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
980 printer->Indent();
981 }
982 last_index = i;
983
984 // It's faster to just overwrite primitive types, but we should
985 // only clear strings and messages if they were set.
986 // TODO(kenton): Let the CppFieldGenerator decide this somehow.
987 bool should_check_bit =
988 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
989 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
990
991 if (should_check_bit) {
992 printer->Print(vars, "if (_has_bit($index$)) {\n");
993 printer->Indent();
994 }
995
996 field_generators_.get(field).GenerateClearingCode(printer);
997
998 if (should_check_bit) {
999 printer->Outdent();
1000 printer->Print("}\n");
1001 }
1002 }
1003 }
1004
1005 if (last_index >= 0) {
1006 printer->Outdent();
1007 printer->Print("}\n");
1008 }
1009
1010 // Repeated fields don't use _has_bits_ so we clear them in a separate
1011 // pass.
1012 for (int i = 0; i < descriptor_->field_count(); i++) {
1013 const FieldDescriptor* field = descriptor_->field(i);
1014
1015 if (field->is_repeated()) {
1016 field_generators_.get(field).GenerateClearingCode(printer);
1017 }
1018 }
1019
1020 printer->Print(
1021 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1022
1023 if (HasUnknownFields(descriptor_->file())) {
1024 printer->Print(
1025 "mutable_unknown_fields()->Clear();\n");
1026 }
1027
1028 printer->Outdent();
1029 printer->Print("}\n");
1030 }
1031
1032 void MessageGenerator::
GenerateSwap(io::Printer * printer)1033 GenerateSwap(io::Printer* printer) {
1034 // Generate the Swap member function.
1035 printer->Print("void $classname$::Swap($classname$* other) {\n",
1036 "classname", classname_);
1037 printer->Indent();
1038 printer->Print("if (other != this) {\n");
1039 printer->Indent();
1040
1041 if (HasGeneratedMethods(descriptor_->file())) {
1042 for (int i = 0; i < descriptor_->field_count(); i++) {
1043 const FieldDescriptor* field = descriptor_->field(i);
1044 field_generators_.get(field).GenerateSwappingCode(printer);
1045 }
1046
1047 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1048 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1049 "i", SimpleItoa(i));
1050 }
1051
1052 if (HasUnknownFields(descriptor_->file())) {
1053 printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
1054 }
1055 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1056 if (descriptor_->extension_range_count() > 0) {
1057 printer->Print("_extensions_.Swap(&other->_extensions_);\n");
1058 }
1059 } else {
1060 printer->Print("GetReflection()->Swap(this, other);");
1061 }
1062
1063 printer->Outdent();
1064 printer->Print("}\n");
1065 printer->Outdent();
1066 printer->Print("}\n");
1067 }
1068
1069 void MessageGenerator::
GenerateMergeFrom(io::Printer * printer)1070 GenerateMergeFrom(io::Printer* printer) {
1071 if (HasDescriptorMethods(descriptor_->file())) {
1072 // Generate the generalized MergeFrom (aka that which takes in the Message
1073 // base class as a parameter).
1074 printer->Print(
1075 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
1076 " GOOGLE_CHECK_NE(&from, this);\n",
1077 "classname", classname_);
1078 printer->Indent();
1079
1080 // Cast the message to the proper type. If we find that the message is
1081 // *not* of the proper type, we can still call Merge via the reflection
1082 // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1083 // for each message.
1084 printer->Print(
1085 "const $classname$* source =\n"
1086 " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1087 " &from);\n"
1088 "if (source == NULL) {\n"
1089 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1090 "} else {\n"
1091 " MergeFrom(*source);\n"
1092 "}\n",
1093 "classname", classname_);
1094
1095 printer->Outdent();
1096 printer->Print("}\n\n");
1097 } else {
1098 // Generate CheckTypeAndMergeFrom().
1099 printer->Print(
1100 "void $classname$::CheckTypeAndMergeFrom(\n"
1101 " const ::google::protobuf::MessageLite& from) {\n"
1102 " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
1103 "}\n"
1104 "\n",
1105 "classname", classname_);
1106 }
1107
1108 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1109 printer->Print(
1110 "void $classname$::MergeFrom(const $classname$& from) {\n"
1111 " GOOGLE_CHECK_NE(&from, this);\n",
1112 "classname", classname_);
1113 printer->Indent();
1114
1115 // Merge Repeated fields. These fields do not require a
1116 // check as we can simply iterate over them.
1117 for (int i = 0; i < descriptor_->field_count(); ++i) {
1118 const FieldDescriptor* field = descriptor_->field(i);
1119
1120 if (field->is_repeated()) {
1121 field_generators_.get(field).GenerateMergingCode(printer);
1122 }
1123 }
1124
1125 // Merge Optional and Required fields (after a _has_bit check).
1126 int last_index = -1;
1127
1128 for (int i = 0; i < descriptor_->field_count(); ++i) {
1129 const FieldDescriptor* field = descriptor_->field(i);
1130
1131 if (!field->is_repeated()) {
1132 map<string, string> vars;
1133 vars["index"] = SimpleItoa(field->index());
1134
1135 // See above in GenerateClear for an explanation of this.
1136 if (i / 8 != last_index / 8 || last_index < 0) {
1137 if (last_index >= 0) {
1138 printer->Outdent();
1139 printer->Print("}\n");
1140 }
1141 printer->Print(vars,
1142 "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
1143 printer->Indent();
1144 }
1145
1146 last_index = i;
1147
1148 printer->Print(vars,
1149 "if (from._has_bit($index$)) {\n");
1150 printer->Indent();
1151
1152 field_generators_.get(field).GenerateMergingCode(printer);
1153
1154 printer->Outdent();
1155 printer->Print("}\n");
1156 }
1157 }
1158
1159 if (last_index >= 0) {
1160 printer->Outdent();
1161 printer->Print("}\n");
1162 }
1163
1164 if (descriptor_->extension_range_count() > 0) {
1165 printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1166 }
1167
1168 if (HasUnknownFields(descriptor_->file())) {
1169 printer->Print(
1170 "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
1171 }
1172
1173 printer->Outdent();
1174 printer->Print("}\n");
1175 }
1176
1177 void MessageGenerator::
GenerateCopyFrom(io::Printer * printer)1178 GenerateCopyFrom(io::Printer* printer) {
1179 if (HasDescriptorMethods(descriptor_->file())) {
1180 // Generate the generalized CopyFrom (aka that which takes in the Message
1181 // base class as a parameter).
1182 printer->Print(
1183 "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1184 "classname", classname_);
1185 printer->Indent();
1186
1187 printer->Print(
1188 "if (&from == this) return;\n"
1189 "Clear();\n"
1190 "MergeFrom(from);\n");
1191
1192 printer->Outdent();
1193 printer->Print("}\n\n");
1194 }
1195
1196 // Generate the class-specific CopyFrom.
1197 printer->Print(
1198 "void $classname$::CopyFrom(const $classname$& from) {\n",
1199 "classname", classname_);
1200 printer->Indent();
1201
1202 printer->Print(
1203 "if (&from == this) return;\n"
1204 "Clear();\n"
1205 "MergeFrom(from);\n");
1206
1207 printer->Outdent();
1208 printer->Print("}\n");
1209 }
1210
1211 void MessageGenerator::
GenerateMergeFromCodedStream(io::Printer * printer)1212 GenerateMergeFromCodedStream(io::Printer* printer) {
1213 if (descriptor_->options().message_set_wire_format()) {
1214 // Special-case MessageSet.
1215 printer->Print(
1216 "bool $classname$::MergePartialFromCodedStream(\n"
1217 " ::google::protobuf::io::CodedInputStream* input) {\n"
1218 " return _extensions_.ParseMessageSet(input, default_instance_,\n"
1219 " mutable_unknown_fields());\n"
1220 "}\n",
1221 "classname", classname_);
1222 return;
1223 }
1224
1225 printer->Print(
1226 "bool $classname$::MergePartialFromCodedStream(\n"
1227 " ::google::protobuf::io::CodedInputStream* input) {\n"
1228 "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
1229 " ::google::protobuf::uint32 tag;\n"
1230 " while ((tag = input->ReadTag()) != 0) {\n",
1231 "classname", classname_);
1232
1233 printer->Indent();
1234 printer->Indent();
1235
1236 if (descriptor_->field_count() > 0) {
1237 // We don't even want to print the switch() if we have no fields because
1238 // MSVC dislikes switch() statements that contain only a default value.
1239
1240 // Note: If we just switched on the tag rather than the field number, we
1241 // could avoid the need for the if() to check the wire type at the beginning
1242 // of each case. However, this is actually a bit slower in practice as it
1243 // creates a jump table that is 8x larger and sparser, and meanwhile the
1244 // if()s are highly predictable.
1245 printer->Print(
1246 "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
1247
1248 printer->Indent();
1249
1250 scoped_array<const FieldDescriptor*> ordered_fields(
1251 SortFieldsByNumber(descriptor_));
1252
1253 for (int i = 0; i < descriptor_->field_count(); i++) {
1254 const FieldDescriptor* field = ordered_fields[i];
1255
1256 PrintFieldComment(printer, field);
1257
1258 printer->Print(
1259 "case $number$: {\n",
1260 "number", SimpleItoa(field->number()));
1261 printer->Indent();
1262 const FieldGenerator& field_generator = field_generators_.get(field);
1263
1264 // Emit code to parse the common, expected case.
1265 printer->Print(
1266 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1267 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
1268 "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
1269
1270 if (i > 0 || (field->is_repeated() && !field->options().packed())) {
1271 printer->Print(
1272 " parse_$name$:\n",
1273 "name", field->name());
1274 }
1275
1276 printer->Indent();
1277 if (field->options().packed()) {
1278 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1279 } else {
1280 field_generator.GenerateMergeFromCodedStream(printer);
1281 }
1282 printer->Outdent();
1283
1284 // Emit code to parse unexpectedly packed or unpacked values.
1285 if (field->is_packable() && field->options().packed()) {
1286 printer->Print(
1287 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1288 " == ::google::protobuf::internal::WireFormatLite::\n"
1289 " WIRETYPE_$wiretype$) {\n",
1290 "wiretype",
1291 kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
1292 printer->Indent();
1293 field_generator.GenerateMergeFromCodedStream(printer);
1294 printer->Outdent();
1295 } else if (field->is_packable() && !field->options().packed()) {
1296 printer->Print(
1297 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1298 " == ::google::protobuf::internal::WireFormatLite::\n"
1299 " WIRETYPE_LENGTH_DELIMITED) {\n");
1300 printer->Indent();
1301 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1302 printer->Outdent();
1303 }
1304
1305 printer->Print(
1306 "} else {\n"
1307 " goto handle_uninterpreted;\n"
1308 "}\n");
1309
1310 // switch() is slow since it can't be predicted well. Insert some if()s
1311 // here that attempt to predict the next tag.
1312 if (field->is_repeated() && !field->options().packed()) {
1313 // Expect repeats of this field.
1314 printer->Print(
1315 "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
1316 "tag", SimpleItoa(WireFormat::MakeTag(field)),
1317 "name", field->name());
1318 }
1319
1320 if (i + 1 < descriptor_->field_count()) {
1321 // Expect the next field in order.
1322 const FieldDescriptor* next_field = ordered_fields[i + 1];
1323 printer->Print(
1324 "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
1325 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
1326 "next_name", next_field->name());
1327 } else {
1328 // Expect EOF.
1329 // TODO(kenton): Expect group end-tag?
1330 printer->Print(
1331 "if (input->ExpectAtEnd()) return true;\n");
1332 }
1333
1334 printer->Print(
1335 "break;\n");
1336
1337 printer->Outdent();
1338 printer->Print("}\n\n");
1339 }
1340
1341 printer->Print(
1342 "default: {\n"
1343 "handle_uninterpreted:\n");
1344 printer->Indent();
1345 }
1346
1347 // Is this an end-group tag? If so, this must be the end of the message.
1348 printer->Print(
1349 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1350 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1351 " return true;\n"
1352 "}\n");
1353
1354 // Handle extension ranges.
1355 if (descriptor_->extension_range_count() > 0) {
1356 printer->Print(
1357 "if (");
1358 for (int i = 0; i < descriptor_->extension_range_count(); i++) {
1359 const Descriptor::ExtensionRange* range =
1360 descriptor_->extension_range(i);
1361 if (i > 0) printer->Print(" ||\n ");
1362
1363 uint32 start_tag = WireFormatLite::MakeTag(
1364 range->start, static_cast<WireFormatLite::WireType>(0));
1365 uint32 end_tag = WireFormatLite::MakeTag(
1366 range->end, static_cast<WireFormatLite::WireType>(0));
1367
1368 if (range->end > FieldDescriptor::kMaxNumber) {
1369 printer->Print(
1370 "($start$u <= tag)",
1371 "start", SimpleItoa(start_tag));
1372 } else {
1373 printer->Print(
1374 "($start$u <= tag && tag < $end$u)",
1375 "start", SimpleItoa(start_tag),
1376 "end", SimpleItoa(end_tag));
1377 }
1378 }
1379 printer->Print(") {\n");
1380 if (HasUnknownFields(descriptor_->file())) {
1381 printer->Print(
1382 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
1383 " mutable_unknown_fields()));\n");
1384 } else {
1385 printer->Print(
1386 " DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
1387 }
1388 printer->Print(
1389 " continue;\n"
1390 "}\n");
1391 }
1392
1393 // We really don't recognize this tag. Skip it.
1394 if (HasUnknownFields(descriptor_->file())) {
1395 printer->Print(
1396 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
1397 " input, tag, mutable_unknown_fields()));\n");
1398 } else {
1399 printer->Print(
1400 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
1401 }
1402
1403 if (descriptor_->field_count() > 0) {
1404 printer->Print("break;\n");
1405 printer->Outdent();
1406 printer->Print("}\n"); // default:
1407 printer->Outdent();
1408 printer->Print("}\n"); // switch
1409 }
1410
1411 printer->Outdent();
1412 printer->Outdent();
1413 printer->Print(
1414 " }\n" // while
1415 " return true;\n"
1416 "#undef DO_\n"
1417 "}\n");
1418 }
1419
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field,bool to_array)1420 void MessageGenerator::GenerateSerializeOneField(
1421 io::Printer* printer, const FieldDescriptor* field, bool to_array) {
1422 PrintFieldComment(printer, field);
1423
1424 if (!field->is_repeated()) {
1425 printer->Print(
1426 "if (_has_bit($index$)) {\n",
1427 "index", SimpleItoa(field->index()));
1428 printer->Indent();
1429 }
1430
1431 if (to_array) {
1432 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
1433 printer);
1434 } else {
1435 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
1436 }
1437
1438 if (!field->is_repeated()) {
1439 printer->Outdent();
1440 printer->Print("}\n");
1441 }
1442 printer->Print("\n");
1443 }
1444
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range,bool to_array)1445 void MessageGenerator::GenerateSerializeOneExtensionRange(
1446 io::Printer* printer, const Descriptor::ExtensionRange* range,
1447 bool to_array) {
1448 map<string, string> vars;
1449 vars["start"] = SimpleItoa(range->start);
1450 vars["end"] = SimpleItoa(range->end);
1451 printer->Print(vars,
1452 "// Extension range [$start$, $end$)\n");
1453 if (to_array) {
1454 printer->Print(vars,
1455 "target = _extensions_.SerializeWithCachedSizesToArray(\n"
1456 " $start$, $end$, target);\n\n");
1457 } else {
1458 printer->Print(vars,
1459 "_extensions_.SerializeWithCachedSizes(\n"
1460 " $start$, $end$, output);\n\n");
1461 }
1462 }
1463
1464 void MessageGenerator::
GenerateSerializeWithCachedSizes(io::Printer * printer)1465 GenerateSerializeWithCachedSizes(io::Printer* printer) {
1466 if (descriptor_->options().message_set_wire_format()) {
1467 // Special-case MessageSet.
1468 printer->Print(
1469 "void $classname$::SerializeWithCachedSizes(\n"
1470 " ::google::protobuf::io::CodedOutputStream* output) const {\n"
1471 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
1472 "classname", classname_);
1473 if (HasUnknownFields(descriptor_->file())) {
1474 printer->Print(
1475 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
1476 " unknown_fields(), output);\n");
1477 }
1478 printer->Print(
1479 "}\n");
1480 return;
1481 }
1482
1483 printer->Print(
1484 "void $classname$::SerializeWithCachedSizes(\n"
1485 " ::google::protobuf::io::CodedOutputStream* output) const {\n",
1486 "classname", classname_);
1487 printer->Indent();
1488
1489 GenerateSerializeWithCachedSizesBody(printer, false);
1490
1491 printer->Outdent();
1492 printer->Print(
1493 "}\n");
1494 }
1495
1496 void MessageGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer * printer)1497 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
1498 if (descriptor_->options().message_set_wire_format()) {
1499 // Special-case MessageSet.
1500 printer->Print(
1501 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1502 " ::google::protobuf::uint8* target) const {\n"
1503 " target =\n"
1504 " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
1505 "classname", classname_);
1506 if (HasUnknownFields(descriptor_->file())) {
1507 printer->Print(
1508 " target = ::google::protobuf::internal::WireFormat::\n"
1509 " SerializeUnknownMessageSetItemsToArray(\n"
1510 " unknown_fields(), target);\n");
1511 }
1512 printer->Print(
1513 " return target;\n"
1514 "}\n");
1515 return;
1516 }
1517
1518 printer->Print(
1519 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1520 " ::google::protobuf::uint8* target) const {\n",
1521 "classname", classname_);
1522 printer->Indent();
1523
1524 GenerateSerializeWithCachedSizesBody(printer, true);
1525
1526 printer->Outdent();
1527 printer->Print(
1528 " return target;\n"
1529 "}\n");
1530 }
1531
1532 void MessageGenerator::
GenerateSerializeWithCachedSizesBody(io::Printer * printer,bool to_array)1533 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
1534 scoped_array<const FieldDescriptor*> ordered_fields(
1535 SortFieldsByNumber(descriptor_));
1536
1537 vector<const Descriptor::ExtensionRange*> sorted_extensions;
1538 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
1539 sorted_extensions.push_back(descriptor_->extension_range(i));
1540 }
1541 sort(sorted_extensions.begin(), sorted_extensions.end(),
1542 ExtensionRangeSorter());
1543
1544 // Merge the fields and the extension ranges, both sorted by field number.
1545 int i, j;
1546 for (i = 0, j = 0;
1547 i < descriptor_->field_count() || j < sorted_extensions.size();
1548 ) {
1549 if (i == descriptor_->field_count()) {
1550 GenerateSerializeOneExtensionRange(printer,
1551 sorted_extensions[j++],
1552 to_array);
1553 } else if (j == sorted_extensions.size()) {
1554 GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1555 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
1556 GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1557 } else {
1558 GenerateSerializeOneExtensionRange(printer,
1559 sorted_extensions[j++],
1560 to_array);
1561 }
1562 }
1563
1564 if (HasUnknownFields(descriptor_->file())) {
1565 printer->Print("if (!unknown_fields().empty()) {\n");
1566 printer->Indent();
1567 if (to_array) {
1568 printer->Print(
1569 "target = "
1570 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
1571 " unknown_fields(), target);\n");
1572 } else {
1573 printer->Print(
1574 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
1575 " unknown_fields(), output);\n");
1576 }
1577 printer->Outdent();
1578
1579 printer->Print(
1580 "}\n");
1581 }
1582 }
1583
1584 void MessageGenerator::
GenerateByteSize(io::Printer * printer)1585 GenerateByteSize(io::Printer* printer) {
1586 if (descriptor_->options().message_set_wire_format()) {
1587 // Special-case MessageSet.
1588 printer->Print(
1589 "int $classname$::ByteSize() const {\n"
1590 " int total_size = _extensions_.MessageSetByteSize();\n",
1591 "classname", classname_);
1592 if (HasUnknownFields(descriptor_->file())) {
1593 printer->Print(
1594 " total_size += ::google::protobuf::internal::WireFormat::\n"
1595 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
1596 }
1597 printer->Print(
1598 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1599 " _cached_size_ = total_size;\n"
1600 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1601 " return total_size;\n"
1602 "}\n");
1603 return;
1604 }
1605
1606 printer->Print(
1607 "int $classname$::ByteSize() const {\n",
1608 "classname", classname_);
1609 printer->Indent();
1610 printer->Print(
1611 "int total_size = 0;\n"
1612 "\n");
1613
1614 int last_index = -1;
1615
1616 for (int i = 0; i < descriptor_->field_count(); i++) {
1617 const FieldDescriptor* field = descriptor_->field(i);
1618
1619 if (!field->is_repeated()) {
1620 // See above in GenerateClear for an explanation of this.
1621 // TODO(kenton): Share code? Unclear how to do so without
1622 // over-engineering.
1623 if ((i / 8) != (last_index / 8) ||
1624 last_index < 0) {
1625 if (last_index >= 0) {
1626 printer->Outdent();
1627 printer->Print("}\n");
1628 }
1629 printer->Print(
1630 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1631 "index", SimpleItoa(field->index()));
1632 printer->Indent();
1633 }
1634 last_index = i;
1635
1636 PrintFieldComment(printer, field);
1637
1638 printer->Print(
1639 "if (has_$name$()) {\n",
1640 "name", FieldName(field));
1641 printer->Indent();
1642
1643 field_generators_.get(field).GenerateByteSize(printer);
1644
1645 printer->Outdent();
1646 printer->Print(
1647 "}\n"
1648 "\n");
1649 }
1650 }
1651
1652 if (last_index >= 0) {
1653 printer->Outdent();
1654 printer->Print("}\n");
1655 }
1656
1657 // Repeated fields don't use _has_bits_ so we count them in a separate
1658 // pass.
1659 for (int i = 0; i < descriptor_->field_count(); i++) {
1660 const FieldDescriptor* field = descriptor_->field(i);
1661
1662 if (field->is_repeated()) {
1663 PrintFieldComment(printer, field);
1664 field_generators_.get(field).GenerateByteSize(printer);
1665 printer->Print("\n");
1666 }
1667 }
1668
1669 if (descriptor_->extension_range_count() > 0) {
1670 printer->Print(
1671 "total_size += _extensions_.ByteSize();\n"
1672 "\n");
1673 }
1674
1675 if (HasUnknownFields(descriptor_->file())) {
1676 printer->Print("if (!unknown_fields().empty()) {\n");
1677 printer->Indent();
1678 printer->Print(
1679 "total_size +=\n"
1680 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
1681 " unknown_fields());\n");
1682 printer->Outdent();
1683 printer->Print("}\n");
1684 }
1685
1686 // We update _cached_size_ even though this is a const method. In theory,
1687 // this is not thread-compatible, because concurrent writes have undefined
1688 // results. In practice, since any concurrent writes will be writing the
1689 // exact same value, it works on all common processors. In a future version
1690 // of C++, _cached_size_ should be made into an atomic<int>.
1691 printer->Print(
1692 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1693 "_cached_size_ = total_size;\n"
1694 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1695 "return total_size;\n");
1696
1697 printer->Outdent();
1698 printer->Print("}\n");
1699 }
1700
1701 void MessageGenerator::
GenerateIsInitialized(io::Printer * printer)1702 GenerateIsInitialized(io::Printer* printer) {
1703 printer->Print(
1704 "bool $classname$::IsInitialized() const {\n",
1705 "classname", classname_);
1706 printer->Indent();
1707
1708 // Check that all required fields in this message are set. We can do this
1709 // most efficiently by checking 32 "has bits" at a time.
1710 int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
1711 for (int i = 0; i < has_bits_array_size; i++) {
1712 uint32 mask = 0;
1713 for (int bit = 0; bit < 32; bit++) {
1714 int index = i * 32 + bit;
1715 if (index >= descriptor_->field_count()) break;
1716 const FieldDescriptor* field = descriptor_->field(index);
1717
1718 if (field->is_required()) {
1719 mask |= 1 << bit;
1720 }
1721 }
1722
1723 if (mask != 0) {
1724 char buffer[kFastToBufferSize];
1725 printer->Print(
1726 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
1727 "i", SimpleItoa(i),
1728 "mask", FastHex32ToBuffer(mask, buffer));
1729 }
1730 }
1731
1732 // Now check that all embedded messages are initialized.
1733 printer->Print("\n");
1734 for (int i = 0; i < descriptor_->field_count(); i++) {
1735 const FieldDescriptor* field = descriptor_->field(i);
1736 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1737 HasRequiredFields(field->message_type())) {
1738 if (field->is_repeated()) {
1739 printer->Print(
1740 "for (int i = 0; i < $name$_size(); i++) {\n"
1741 " if (!this->$name$(i).IsInitialized()) return false;\n"
1742 "}\n",
1743 "name", FieldName(field));
1744 } else {
1745 printer->Print(
1746 "if (has_$name$()) {\n"
1747 " if (!this->$name$().IsInitialized()) return false;\n"
1748 "}\n",
1749 "name", FieldName(field));
1750 }
1751 }
1752 }
1753
1754 if (descriptor_->extension_range_count() > 0) {
1755 printer->Print(
1756 "\n"
1757 "if (!_extensions_.IsInitialized()) return false;");
1758 }
1759
1760 printer->Outdent();
1761 printer->Print(
1762 " return true;\n"
1763 "}\n");
1764 }
1765
1766
1767 } // namespace cpp
1768 } // namespace compiler
1769 } // namespace protobuf
1770 } // namespace google
1771