• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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