1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <algorithm>
36 #include <google/protobuf/stubs/hash.h>
37 #include <map>
38 #include <memory>
39 #ifndef _SHARED_PTR_H
40 #include <google/protobuf/stubs/shared_ptr.h>
41 #endif
42 #include <utility>
43 #include <vector>
44 #include <google/protobuf/compiler/cpp/cpp_message.h>
45 #include <google/protobuf/compiler/cpp/cpp_field.h>
46 #include <google/protobuf/compiler/cpp/cpp_enum.h>
47 #include <google/protobuf/compiler/cpp/cpp_extension.h>
48 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
49 #include <google/protobuf/stubs/strutil.h>
50 #include <google/protobuf/io/printer.h>
51 #include <google/protobuf/io/coded_stream.h>
52 #include <google/protobuf/wire_format.h>
53 #include <google/protobuf/descriptor.pb.h>
54 
55 
56 namespace google {
57 namespace protobuf {
58 namespace compiler {
59 namespace cpp {
60 
61 using internal::WireFormat;
62 using internal::WireFormatLite;
63 
64 namespace {
65 
66 template <class T>
PrintFieldComment(io::Printer * printer,const T * field)67 void PrintFieldComment(io::Printer* printer, const T* field) {
68   // Print the field's (or oneof's) proto-syntax definition as a comment.
69   // We don't want to print group bodies so we cut off after the first
70   // line.
71   DebugStringOptions options;
72   options.elide_group_body = true;
73   options.elide_oneof_body = true;
74   string def = field->DebugStringWithOptions(options);
75   printer->Print("// $def$\n",
76     "def", def.substr(0, def.find_first_of('\n')));
77 }
78 
79 struct FieldOrderingByNumber {
operator ()google::protobuf::compiler::cpp::__anoned4e23cb0111::FieldOrderingByNumber80   inline bool operator()(const FieldDescriptor* a,
81                          const FieldDescriptor* b) const {
82     return a->number() < b->number();
83   }
84 };
85 
86 // Sort the fields of the given Descriptor by number into a new[]'d array
87 // and return it.
SortFieldsByNumber(const Descriptor * descriptor)88 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
89   const FieldDescriptor** fields =
90     new const FieldDescriptor*[descriptor->field_count()];
91   for (int i = 0; i < descriptor->field_count(); i++) {
92     fields[i] = descriptor->field(i);
93   }
94   std::sort(fields, fields + descriptor->field_count(),
95             FieldOrderingByNumber());
96   return fields;
97 }
98 
99 // Functor for sorting extension ranges by their "start" field number.
100 struct ExtensionRangeSorter {
operator ()google::protobuf::compiler::cpp::__anoned4e23cb0111::ExtensionRangeSorter101   bool operator()(const Descriptor::ExtensionRange* left,
102                   const Descriptor::ExtensionRange* right) const {
103     return left->start < right->start;
104   }
105 };
106 
107 // Returns true if the "required" restriction check should be ignored for the
108 // given field.
ShouldIgnoreRequiredFieldCheck(const FieldDescriptor * field,const Options & options)109 inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
110                                                   const Options& options) {
111   return false;
112 }
113 
114 // Returns true if the message type has any required fields.  If it doesn't,
115 // we can optimize out calls to its IsInitialized() method.
116 //
117 // already_seen is used to avoid checking the same type multiple times
118 // (and also to protect against recursion).
HasRequiredFields(const Descriptor * type,const Options & options,hash_set<const Descriptor * > * already_seen)119 static bool HasRequiredFields(const Descriptor* type, const Options& options,
120                               hash_set<const Descriptor*>* already_seen) {
121   if (already_seen->count(type) > 0) {
122     // Since the first occurrence of a required field causes the whole
123     // function to return true, we can assume that if the type is already
124     // in the cache it didn't have any required fields.
125     return false;
126   }
127   already_seen->insert(type);
128 
129   // If the type has extensions, an extension with message type could contain
130   // required fields, so we have to be conservative and assume such an
131   // extension exists.
132   if (type->extension_range_count() > 0) return true;
133 
134   for (int i = 0; i < type->field_count(); i++) {
135     const FieldDescriptor* field = type->field(i);
136     if (field->is_required()) {
137       return true;
138     }
139     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
140         !ShouldIgnoreRequiredFieldCheck(field, options)) {
141       if (HasRequiredFields(field->message_type(), options, already_seen)) {
142         return true;
143       }
144     }
145   }
146 
147   return false;
148 }
149 
HasRequiredFields(const Descriptor * type,const Options & options)150 static bool HasRequiredFields(const Descriptor* type, const Options& options) {
151   hash_set<const Descriptor*> already_seen;
152   return HasRequiredFields(type, options, &already_seen);
153 }
154 
155 // This returns an estimate of the compiler's alignment for the field.  This
156 // can't guarantee to be correct because the generated code could be compiled on
157 // different systems with different alignment rules.  The estimates below assume
158 // 64-bit pointers.
EstimateAlignmentSize(const FieldDescriptor * field)159 int EstimateAlignmentSize(const FieldDescriptor* field) {
160   if (field == NULL) return 0;
161   if (field->is_repeated()) return 8;
162   switch (field->cpp_type()) {
163     case FieldDescriptor::CPPTYPE_BOOL:
164       return 1;
165 
166     case FieldDescriptor::CPPTYPE_INT32:
167     case FieldDescriptor::CPPTYPE_UINT32:
168     case FieldDescriptor::CPPTYPE_ENUM:
169     case FieldDescriptor::CPPTYPE_FLOAT:
170       return 4;
171 
172     case FieldDescriptor::CPPTYPE_INT64:
173     case FieldDescriptor::CPPTYPE_UINT64:
174     case FieldDescriptor::CPPTYPE_DOUBLE:
175     case FieldDescriptor::CPPTYPE_STRING:
176     case FieldDescriptor::CPPTYPE_MESSAGE:
177       return 8;
178   }
179   GOOGLE_LOG(FATAL) << "Can't get here.";
180   return -1;  // Make compiler happy.
181 }
182 
183 // FieldGroup is just a helper for OptimizePadding below.  It holds a vector of
184 // fields that are grouped together because they have compatible alignment, and
185 // a preferred location in the final field ordering.
186 class FieldGroup {
187  public:
FieldGroup()188   FieldGroup()
189       : preferred_location_(0) {}
190 
191   // A group with a single field.
FieldGroup(float preferred_location,const FieldDescriptor * field)192   FieldGroup(float preferred_location, const FieldDescriptor* field)
193       : preferred_location_(preferred_location),
194         fields_(1, field) {}
195 
196   // Append the fields in 'other' to this group.
Append(const FieldGroup & other)197   void Append(const FieldGroup& other) {
198     if (other.fields_.empty()) {
199       return;
200     }
201     // Preferred location is the average among all the fields, so we weight by
202     // the number of fields on each FieldGroup object.
203     preferred_location_ =
204         (preferred_location_ * fields_.size() +
205          (other.preferred_location_ * other.fields_.size())) /
206         (fields_.size() + other.fields_.size());
207     fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
208   }
209 
SetPreferredLocation(float location)210   void SetPreferredLocation(float location) { preferred_location_ = location; }
fields() const211   const vector<const FieldDescriptor*>& fields() const { return fields_; }
212 
213   // FieldGroup objects sort by their preferred location.
operator <(const FieldGroup & other) const214   bool operator<(const FieldGroup& other) const {
215     return preferred_location_ < other.preferred_location_;
216   }
217 
218  private:
219   // "preferred_location_" is an estimate of where this group should go in the
220   // final list of fields.  We compute this by taking the average index of each
221   // field in this group in the original ordering of fields.  This is very
222   // approximate, but should put this group close to where its member fields
223   // originally went.
224   float preferred_location_;
225   vector<const FieldDescriptor*> fields_;
226   // We rely on the default copy constructor and operator= so this type can be
227   // used in a vector.
228 };
229 
230 // Reorder 'fields' so that if the fields are output into a c++ class in the new
231 // order, the alignment padding is minimized.  We try to do this while keeping
232 // each field as close as possible to its original position so that we don't
233 // reduce cache locality much for function that access each field in order.
OptimizePadding(vector<const FieldDescriptor * > * fields)234 void OptimizePadding(vector<const FieldDescriptor*>* fields) {
235   // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
236   vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
237   for (int i = 0; i < fields->size(); ++i) {
238     switch (EstimateAlignmentSize((*fields)[i])) {
239       case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
240       case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
241       case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
242       default:
243         GOOGLE_LOG(FATAL) << "Unknown alignment size.";
244     }
245   }
246 
247   // Now group fields aligned to 1 byte into sets of 4, and treat those like a
248   // single field aligned to 4 bytes.
249   for (int i = 0; i < aligned_to_1.size(); i += 4) {
250     FieldGroup field_group;
251     for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
252       field_group.Append(aligned_to_1[j]);
253     }
254     aligned_to_4.push_back(field_group);
255   }
256   // Sort by preferred location to keep fields as close to their original
257   // location as possible.  Using stable_sort ensures that the output is
258   // consistent across runs.
259   std::stable_sort(aligned_to_4.begin(), aligned_to_4.end());
260 
261   // Now group fields aligned to 4 bytes (or the 4-field groups created above)
262   // into pairs, and treat those like a single field aligned to 8 bytes.
263   for (int i = 0; i < aligned_to_4.size(); i += 2) {
264     FieldGroup field_group;
265     for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
266       field_group.Append(aligned_to_4[j]);
267     }
268     if (i == aligned_to_4.size() - 1) {
269       // Move incomplete 4-byte block to the end.
270       field_group.SetPreferredLocation(fields->size() + 1);
271     }
272     aligned_to_8.push_back(field_group);
273   }
274   // Sort by preferred location.
275   std::stable_sort(aligned_to_8.begin(), aligned_to_8.end());
276 
277   // Now pull out all the FieldDescriptors in order.
278   fields->clear();
279   for (int i = 0; i < aligned_to_8.size(); ++i) {
280     fields->insert(fields->end(),
281                    aligned_to_8[i].fields().begin(),
282                    aligned_to_8[i].fields().end());
283   }
284 }
285 
MessageTypeProtoName(const FieldDescriptor * field)286 string MessageTypeProtoName(const FieldDescriptor* field) {
287   return field->message_type()->full_name();
288 }
289 
290 // Emits an if-statement with a condition that evaluates to true if |field| is
291 // considered non-default (will be sent over the wire), for message types
292 // without true field presence. Should only be called if
293 // !HasFieldPresence(message_descriptor).
EmitFieldNonDefaultCondition(io::Printer * printer,const string & prefix,const FieldDescriptor * field)294 bool EmitFieldNonDefaultCondition(io::Printer* printer,
295                                   const string& prefix,
296                                   const FieldDescriptor* field) {
297   // Merge and serialize semantics: primitive fields are merged/serialized only
298   // if non-zero (numeric) or non-empty (string).
299   if (!field->is_repeated() && !field->containing_oneof()) {
300     if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
301       printer->Print(
302           "if ($prefix$$name$().size() > 0) {\n",
303           "prefix", prefix,
304           "name", FieldName(field));
305     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
306       // Message fields still have has_$name$() methods.
307       printer->Print(
308           "if ($prefix$has_$name$()) {\n",
309           "prefix", prefix,
310           "name", FieldName(field));
311     } else {
312       printer->Print(
313           "if ($prefix$$name$() != 0) {\n",
314           "prefix", prefix,
315           "name", FieldName(field));
316     }
317     printer->Indent();
318     return true;
319   } else if (field->containing_oneof()) {
320     printer->Print(
321         "if (has_$name$()) {\n",
322         "name", FieldName(field));
323     printer->Indent();
324     return true;
325   }
326   return false;
327 }
328 
329 // Does the given field have a has_$name$() method?
HasHasMethod(const FieldDescriptor * field)330 bool HasHasMethod(const FieldDescriptor* field) {
331   if (HasFieldPresence(field->file())) {
332     // In proto1/proto2, every field has a has_$name$() method.
333     return true;
334   }
335   // For message types without true field presence, only fields with a message
336   // type have a has_$name$() method.
337   return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE;
338 }
339 
340 // Collects map entry message type information.
CollectMapInfo(const Descriptor * descriptor,map<string,string> * variables)341 void CollectMapInfo(const Descriptor* descriptor,
342                     map<string, string>* variables) {
343   GOOGLE_CHECK(IsMapEntryMessage(descriptor));
344   const FieldDescriptor* key = descriptor->FindFieldByName("key");
345   const FieldDescriptor* val = descriptor->FindFieldByName("value");
346   (*variables)["key"] = PrimitiveTypeName(key->cpp_type());
347   switch (val->cpp_type()) {
348     case FieldDescriptor::CPPTYPE_MESSAGE:
349       (*variables)["val"] = FieldMessageTypeName(val);
350       break;
351     case FieldDescriptor::CPPTYPE_ENUM:
352       (*variables)["val"] = ClassName(val->enum_type(), true);
353       break;
354     default:
355       (*variables)["val"] = PrimitiveTypeName(val->cpp_type());
356   }
357   (*variables)["key_wire_type"] =
358       "::google::protobuf::internal::WireFormatLite::TYPE_" +
359       ToUpper(DeclaredTypeMethodName(key->type()));
360   (*variables)["val_wire_type"] =
361       "::google::protobuf::internal::WireFormatLite::TYPE_" +
362       ToUpper(DeclaredTypeMethodName(val->type()));
363 }
364 
365 // Does the given field have a private (internal helper only) has_$name$()
366 // method?
HasPrivateHasMethod(const FieldDescriptor * field)367 bool HasPrivateHasMethod(const FieldDescriptor* field) {
368   // Only for oneofs in message types with no field presence. has_$name$(),
369   // based on the oneof case, is still useful internally for generated code.
370   return (!HasFieldPresence(field->file()) &&
371           field->containing_oneof() != NULL);
372 }
373 
374 }  // anonymous namespace
375 
376 // ===================================================================
377 
MessageGenerator(const Descriptor * descriptor,const Options & options)378 MessageGenerator::MessageGenerator(const Descriptor* descriptor,
379                                    const Options& options)
380     : descriptor_(descriptor),
381       classname_(ClassName(descriptor, false)),
382       options_(options),
383       field_generators_(descriptor, options),
384       nested_generators_(new google::protobuf::scoped_ptr<
385           MessageGenerator>[descriptor->nested_type_count()]),
386       enum_generators_(
387           new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
388       extension_generators_(new google::protobuf::scoped_ptr<
389           ExtensionGenerator>[descriptor->extension_count()]),
390       use_dependent_base_(false) {
391 
392   for (int i = 0; i < descriptor->nested_type_count(); i++) {
393     nested_generators_[i].reset(
394       new MessageGenerator(descriptor->nested_type(i), options));
395   }
396 
397   for (int i = 0; i < descriptor->enum_type_count(); i++) {
398     enum_generators_[i].reset(
399       new EnumGenerator(descriptor->enum_type(i), options));
400   }
401 
402   for (int i = 0; i < descriptor->extension_count(); i++) {
403     extension_generators_[i].reset(
404       new ExtensionGenerator(descriptor->extension(i), options));
405   }
406 
407   num_required_fields_ = 0;
408   for (int i = 0; i < descriptor->field_count(); i++) {
409     if (descriptor->field(i)->is_required()) {
410       ++num_required_fields_;
411     }
412     if (options.proto_h && IsFieldDependent(descriptor->field(i))) {
413       use_dependent_base_ = true;
414     }
415   }
416   if (options.proto_h && descriptor->oneof_decl_count() > 0) {
417     // Always make oneofs dependent.
418     use_dependent_base_ = true;
419   }
420 }
421 
~MessageGenerator()422 MessageGenerator::~MessageGenerator() {}
423 
424 void MessageGenerator::
FillMessageForwardDeclarations(map<string,const Descriptor * > * class_names)425 FillMessageForwardDeclarations(map<string, const Descriptor*>* class_names) {
426   (*class_names)[classname_] = descriptor_;
427 
428   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
429     // map entry message doesn't need forward declaration. Since map entry
430     // message cannot be a top level class, we just need to avoid calling
431     // GenerateForwardDeclaration here.
432     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
433     nested_generators_[i]->FillMessageForwardDeclarations(class_names);
434   }
435 }
436 
437 void MessageGenerator::
FillEnumForwardDeclarations(map<string,const EnumDescriptor * > * enum_names)438 FillEnumForwardDeclarations(map<string, const EnumDescriptor*>* enum_names) {
439   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
440     nested_generators_[i]->FillEnumForwardDeclarations(enum_names);
441   }
442   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
443     enum_generators_[i]->FillForwardDeclaration(enum_names);
444   }
445 }
446 
447 void MessageGenerator::
GenerateEnumDefinitions(io::Printer * printer)448 GenerateEnumDefinitions(io::Printer* printer) {
449   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
450     nested_generators_[i]->GenerateEnumDefinitions(printer);
451   }
452 
453   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
454     enum_generators_[i]->GenerateDefinition(printer);
455   }
456 }
457 
458 void MessageGenerator::
GenerateGetEnumDescriptorSpecializations(io::Printer * printer)459 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
460   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
461     nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
462   }
463   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
464     enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
465   }
466 }
467 
468 void MessageGenerator::
GenerateDependentFieldAccessorDeclarations(io::Printer * printer)469 GenerateDependentFieldAccessorDeclarations(io::Printer* printer) {
470   for (int i = 0; i < descriptor_->field_count(); i++) {
471     const FieldDescriptor* field = descriptor_->field(i);
472 
473     PrintFieldComment(printer, field);
474 
475     map<string, string> vars;
476     SetCommonFieldVariables(field, &vars, options_);
477 
478     if (use_dependent_base_ && IsFieldDependent(field)) {
479       // If the message is dependent, the inline clear_*() method will need
480       // to delete the message type, so it must be in the dependent base
481       // class. (See also GenerateFieldAccessorDeclarations.)
482       printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
483     }
484     // Generate type-specific accessor declarations.
485     field_generators_.get(field).GenerateDependentAccessorDeclarations(printer);
486     printer->Print("\n");
487   }
488 }
489 
490 void MessageGenerator::
GenerateFieldAccessorDeclarations(io::Printer * printer)491 GenerateFieldAccessorDeclarations(io::Printer* printer) {
492   for (int i = 0; i < descriptor_->field_count(); i++) {
493     const FieldDescriptor* field = descriptor_->field(i);
494 
495     PrintFieldComment(printer, field);
496 
497     map<string, string> vars;
498     SetCommonFieldVariables(field, &vars, options_);
499     vars["constant_name"] = FieldConstantName(field);
500 
501     bool dependent_field = use_dependent_base_ && IsFieldDependent(field);
502     if (dependent_field &&
503         field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
504         !field->is_map()) {
505       // If this field is dependent, the dependent base class determines
506       // the message type from the derived class (which is a template
507       // parameter). This typedef is for that:
508       printer->Print(
509           "private:\n"
510           "typedef $field_type$ $dependent_type$;\n"
511           "public:\n",
512           "field_type", FieldMessageTypeName(field),
513           "dependent_type", DependentTypeName(field));
514     }
515 
516     if (field->is_repeated()) {
517       printer->Print(vars, "$deprecated_attr$int $name$_size() const;\n");
518     } else if (HasHasMethod(field)) {
519       printer->Print(vars, "$deprecated_attr$bool has_$name$() const;\n");
520     } else if (HasPrivateHasMethod(field)) {
521       printer->Print(vars,
522           "private:\n"
523           "bool has_$name$() const;\n"
524           "public:\n");
525     }
526 
527     if (!dependent_field) {
528       // If this field is dependent, then its clear_() method is in the
529       // depenent base class. (See also GenerateDependentAccessorDeclarations.)
530       printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
531     }
532     printer->Print(vars,
533                    "$deprecated_attr$static const int $constant_name$ = "
534                    "$number$;\n");
535 
536     // Generate type-specific accessor declarations.
537     field_generators_.get(field).GenerateAccessorDeclarations(printer);
538 
539     printer->Print("\n");
540   }
541 
542   if (descriptor_->extension_range_count() > 0) {
543     // Generate accessors for extensions.  We just call a macro located in
544     // extension_set.h since the accessors about 80 lines of static code.
545     printer->Print(
546       "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
547       "classname", classname_);
548   }
549 
550   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
551     printer->Print(
552         "$camel_oneof_name$Case $oneof_name$_case() const;\n",
553         "camel_oneof_name",
554         UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
555         "oneof_name", descriptor_->oneof_decl(i)->name());
556   }
557 }
558 
559 void MessageGenerator::
GenerateDependentFieldAccessorDefinitions(io::Printer * printer)560 GenerateDependentFieldAccessorDefinitions(io::Printer* printer) {
561   if (!use_dependent_base_) return;
562 
563   printer->Print("// $classname$\n\n", "classname",
564                  DependentBaseClassTemplateName(descriptor_));
565 
566   for (int i = 0; i < descriptor_->field_count(); i++) {
567     const FieldDescriptor* field = descriptor_->field(i);
568 
569     PrintFieldComment(printer, field);
570 
571     // These functions are not really dependent: they are part of the
572     // (non-dependent) derived class. However, they need to live outside
573     // any #ifdef guards, so we treat them as if they were dependent.
574     //
575     // See the comment in FileGenerator::GenerateInlineFunctionDefinitions
576     // for a more complete explanation.
577     if (use_dependent_base_ && IsFieldDependent(field)) {
578       map<string, string> vars;
579       SetCommonFieldVariables(field, &vars, options_);
580       vars["inline"] = "inline ";
581       if (field->containing_oneof()) {
582         vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
583         vars["oneof_name"] = field->containing_oneof()->name();
584         vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
585         GenerateOneofMemberHasBits(field, vars, printer);
586       } else if (!field->is_repeated()) {
587         // There will be no header guard, so this always has to be inline.
588         GenerateSingularFieldHasBits(field, vars, printer);
589       }
590       // vars needed for clear_(), which is in the dependent base:
591       // (See also GenerateDependentFieldAccessorDeclarations.)
592       vars["tmpl"] = "template<class T>\n";
593       vars["dependent_classname"] =
594           DependentBaseClassTemplateName(descriptor_) + "<T>";
595       vars["this_message"] = DependentBaseDownCast();
596       vars["this_const_message"] = DependentBaseConstDownCast();
597       GenerateFieldClear(field, vars, printer);
598     }
599 
600     // Generate type-specific accessors.
601     field_generators_.get(field)
602         .GenerateDependentInlineAccessorDefinitions(printer);
603 
604     printer->Print("\n");
605   }
606 
607   // Generate has_$name$() and clear_has_$name$() functions for oneofs
608   // Similar to other has-bits, these must always be in the header if we
609   // are using a dependent base class.
610   GenerateOneofHasBits(printer, true /* is_inline */);
611 }
612 
613 void MessageGenerator::
GenerateSingularFieldHasBits(const FieldDescriptor * field,map<string,string> vars,io::Printer * printer)614 GenerateSingularFieldHasBits(const FieldDescriptor* field,
615                              map<string, string> vars,
616                              io::Printer* printer) {
617   if (HasFieldPresence(descriptor_->file())) {
618     // N.B.: without field presence, we do not use has-bits or generate
619     // has_$name$() methods.
620     vars["has_array_index"] = SimpleItoa(field->index() / 32);
621     vars["has_mask"] = StrCat(strings::Hex(1u << (field->index() % 32),
622                                            strings::ZERO_PAD_8));
623     printer->Print(vars,
624       "$inline$"
625       "bool $classname$::has_$name$() const {\n"
626       "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
627       "}\n"
628       "$inline$"
629       "void $classname$::set_has_$name$() {\n"
630       "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
631       "}\n"
632       "$inline$"
633       "void $classname$::clear_has_$name$() {\n"
634       "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
635       "}\n");
636   } else {
637     // Message fields have a has_$name$() method.
638     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
639       bool is_lazy = false;
640       if (is_lazy) {
641         printer->Print(vars,
642           "$inline$"
643           "bool $classname$::has_$name$() const {\n"
644           "  return !$name$_.IsCleared();\n"
645           "}\n");
646       } else {
647         printer->Print(vars,
648           "$inline$"
649           "bool $classname$::has_$name$() const {\n"
650           "  return !_is_default_instance_ && $name$_ != NULL;\n"
651           "}\n");
652       }
653     }
654   }
655 }
656 
657 void MessageGenerator::
GenerateOneofHasBits(io::Printer * printer,bool is_inline)658 GenerateOneofHasBits(io::Printer* printer, bool is_inline) {
659   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
660     map<string, string> vars;
661     vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
662     vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
663     vars["cap_oneof_name"] =
664         ToUpper(descriptor_->oneof_decl(i)->name());
665     vars["classname"] = classname_;
666     vars["inline"] = (is_inline ? "inline " : "");
667     printer->Print(
668         vars,
669         "$inline$"
670         "bool $classname$::has_$oneof_name$() const {\n"
671         "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
672         "}\n"
673         "$inline$"
674         "void $classname$::clear_has_$oneof_name$() {\n"
675         "  _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
676         "}\n");
677   }
678 }
679 
680 void MessageGenerator::
GenerateOneofMemberHasBits(const FieldDescriptor * field,const map<string,string> & vars,io::Printer * printer)681 GenerateOneofMemberHasBits(const FieldDescriptor* field,
682                            const map<string, string>& vars,
683                            io::Printer* printer) {
684   // Singular field in a oneof
685   // N.B.: Without field presence, we do not use has-bits or generate
686   // has_$name$() methods, but oneofs still have set_has_$name$().
687   // Oneofs also have has_$name$() but only as a private helper
688   // method, so that generated code is slightly cleaner (vs.  comparing
689   // _oneof_case_[index] against a constant everywhere).
690   printer->Print(vars,
691     "$inline$"
692     "bool $classname$::has_$name$() const {\n"
693     "  return $oneof_name$_case() == k$field_name$;\n"
694     "}\n");
695   printer->Print(vars,
696     "$inline$"
697     "void $classname$::set_has_$name$() {\n"
698     "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
699     "}\n");
700 }
701 
702 void MessageGenerator::
GenerateFieldClear(const FieldDescriptor * field,const map<string,string> & vars,io::Printer * printer)703 GenerateFieldClear(const FieldDescriptor* field,
704                    const map<string, string>& vars,
705                    io::Printer* printer) {
706   // Generate clear_$name$() (See GenerateFieldAccessorDeclarations and
707   // GenerateDependentFieldAccessorDeclarations, $dependent_classname$ is
708   // set by the Generate*Definitions functions.)
709   printer->Print(vars,
710     "$tmpl$"
711     "$inline$"
712     "void $dependent_classname$::clear_$name$() {\n");
713 
714   printer->Indent();
715 
716   if (field->containing_oneof()) {
717     // Clear this field only if it is the active field in this oneof,
718     // otherwise ignore
719     printer->Print(vars,
720       "if ($this_message$has_$name$()) {\n");
721     printer->Indent();
722     field_generators_.get(field)
723         .GenerateClearingCode(printer);
724     printer->Print(vars,
725       "$this_message$clear_has_$oneof_name$();\n");
726     printer->Outdent();
727     printer->Print("}\n");
728   } else {
729     field_generators_.get(field)
730         .GenerateClearingCode(printer);
731     if (HasFieldPresence(descriptor_->file())) {
732       if (!field->is_repeated()) {
733         printer->Print(vars,
734                        "$this_message$clear_has_$name$();\n");
735       }
736     }
737   }
738 
739   printer->Outdent();
740   printer->Print("}\n");
741 }
742 
743 void MessageGenerator::
GenerateFieldAccessorDefinitions(io::Printer * printer,bool is_inline)744 GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
745   printer->Print("// $classname$\n\n", "classname", classname_);
746 
747   for (int i = 0; i < descriptor_->field_count(); i++) {
748     const FieldDescriptor* field = descriptor_->field(i);
749 
750     PrintFieldComment(printer, field);
751 
752     map<string, string> vars;
753     SetCommonFieldVariables(field, &vars, options_);
754     vars["inline"] = is_inline ? "inline " : "";
755     if (use_dependent_base_ && IsFieldDependent(field)) {
756       vars["tmpl"] = "template<class T>\n";
757       vars["dependent_classname"] =
758           DependentBaseClassTemplateName(descriptor_) + "<T>";
759       vars["this_message"] = "reinterpret_cast<T*>(this)->";
760       vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
761     } else {
762       vars["tmpl"] = "";
763       vars["dependent_classname"] = vars["classname"];
764       vars["this_message"] = "";
765       vars["this_const_message"] = "";
766     }
767 
768     // Generate has_$name$() or $name$_size().
769     if (field->is_repeated()) {
770       printer->Print(vars,
771         "$inline$"
772         "int $classname$::$name$_size() const {\n"
773         "  return $name$_.size();\n"
774         "}\n");
775     } else if (field->containing_oneof()) {
776       vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
777       vars["oneof_name"] = field->containing_oneof()->name();
778       vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
779       if (!use_dependent_base_ || !IsFieldDependent(field)) {
780         GenerateOneofMemberHasBits(field, vars, printer);
781       }
782     } else {
783       // Singular field.
784       if (!use_dependent_base_ || !IsFieldDependent(field)) {
785         GenerateSingularFieldHasBits(field, vars, printer);
786       }
787     }
788 
789     if (!use_dependent_base_ || !IsFieldDependent(field)) {
790       GenerateFieldClear(field, vars, printer);
791     }
792 
793     // Generate type-specific accessors.
794     field_generators_.get(field).GenerateInlineAccessorDefinitions(printer,
795                                                                    is_inline);
796 
797     printer->Print("\n");
798   }
799 
800   if (!use_dependent_base_) {
801     // Generate has_$name$() and clear_has_$name$() functions for oneofs
802     // If we aren't using a dependent base, they can be with the other functions
803     // that are #ifdef-guarded.
804     GenerateOneofHasBits(printer, is_inline);
805   }
806 }
807 
808 // Helper for the code that emits the Clear() method.
CanClearByZeroing(const FieldDescriptor * field)809 static bool CanClearByZeroing(const FieldDescriptor* field) {
810   if (field->is_repeated() || field->is_extension()) return false;
811   switch (field->cpp_type()) {
812     case internal::WireFormatLite::CPPTYPE_ENUM:
813       return field->default_value_enum()->number() == 0;
814     case internal::WireFormatLite::CPPTYPE_INT32:
815       return field->default_value_int32() == 0;
816     case internal::WireFormatLite::CPPTYPE_INT64:
817       return field->default_value_int64() == 0;
818     case internal::WireFormatLite::CPPTYPE_UINT32:
819       return field->default_value_uint32() == 0;
820     case internal::WireFormatLite::CPPTYPE_UINT64:
821       return field->default_value_uint64() == 0;
822     case internal::WireFormatLite::CPPTYPE_FLOAT:
823       return field->default_value_float() == 0;
824     case internal::WireFormatLite::CPPTYPE_DOUBLE:
825       return field->default_value_double() == 0;
826     case internal::WireFormatLite::CPPTYPE_BOOL:
827       return field->default_value_bool() == false;
828     default:
829       return false;
830   }
831 }
832 
833 void MessageGenerator::
GenerateDependentBaseClassDefinition(io::Printer * printer)834 GenerateDependentBaseClassDefinition(io::Printer* printer) {
835   if (!use_dependent_base_) {
836     return;
837   }
838 
839   map<string, string> vars;
840   vars["classname"] = DependentBaseClassTemplateName(descriptor_);
841   vars["full_name"] = descriptor_->full_name();
842   vars["superclass"] = SuperClassName(descriptor_, options_);
843 
844   printer->Print(vars,
845     "template <class T>\n"
846     "class $classname$ : public $superclass$ "
847     "/* @@protoc_insertion_point(dep_base_class_definition:$full_name$) */ {\n"
848     " public:\n");
849   printer->Indent();
850 
851   printer->Print(vars,
852     "$classname$() {}\n"
853     "virtual ~$classname$() {}\n"
854     "\n");
855 
856   // Generate dependent accessor methods for all fields.
857   GenerateDependentFieldAccessorDeclarations(printer);
858 
859   printer->Outdent();
860   printer->Print("};\n");
861 }
862 
863 void MessageGenerator::
GenerateClassDefinition(io::Printer * printer)864 GenerateClassDefinition(io::Printer* printer) {
865   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
866     // map entry message doesn't need class definition. Since map entry message
867     // cannot be a top level class, we just need to avoid calling
868     // GenerateClassDefinition here.
869     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
870     nested_generators_[i]->GenerateClassDefinition(printer);
871     printer->Print("\n");
872     printer->Print(kThinSeparator);
873     printer->Print("\n");
874   }
875 
876   if (use_dependent_base_) {
877     GenerateDependentBaseClassDefinition(printer);
878       printer->Print("\n");
879   }
880 
881   map<string, string> vars;
882   vars["classname"] = classname_;
883   vars["full_name"] = descriptor_->full_name();
884   vars["field_count"] = SimpleItoa(descriptor_->field_count());
885   vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
886   if (options_.dllexport_decl.empty()) {
887     vars["dllexport"] = "";
888   } else {
889     vars["dllexport"] = options_.dllexport_decl + " ";
890   }
891   if (use_dependent_base_) {
892     vars["superclass"] =
893         DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
894   } else {
895     vars["superclass"] = SuperClassName(descriptor_, options_);
896   }
897   printer->Print(vars,
898     "class $dllexport$$classname$ : public $superclass$ "
899     "/* @@protoc_insertion_point(class_definition:$full_name$) */ "
900     "{\n");
901   printer->Annotate("classname", descriptor_);
902   if (use_dependent_base_) {
903     printer->Print(vars, "  friend class $superclass$;\n");
904   }
905   printer->Print(" public:\n");
906   printer->Indent();
907 
908   printer->Print(vars,
909     "$classname$();\n"
910     "virtual ~$classname$();\n"
911     "\n"
912     "$classname$(const $classname$& from);\n"
913     "\n"
914     "inline $classname$& operator=(const $classname$& from) {\n"
915     "  CopyFrom(from);\n"
916     "  return *this;\n"
917     "}\n"
918     "\n");
919 
920   if (PreserveUnknownFields(descriptor_)) {
921     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
922       printer->Print(
923         "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
924         "  return _internal_metadata_.unknown_fields();\n"
925         "}\n"
926         "\n"
927         "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
928         "  return _internal_metadata_.mutable_unknown_fields();\n"
929         "}\n"
930         "\n");
931     } else {
932       if (SupportsArenas(descriptor_)) {
933         printer->Print(
934           "inline const ::std::string& unknown_fields() const {\n"
935           "  return _unknown_fields_.Get(\n"
936           "      &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
937           "}\n"
938           "\n"
939           "inline ::std::string* mutable_unknown_fields() {\n"
940           "  return _unknown_fields_.Mutable(\n"
941           "      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
942           "      GetArenaNoVirtual());\n"
943           "}\n"
944           "\n");
945       } else {
946         printer->Print(
947           "inline const ::std::string& unknown_fields() const {\n"
948           "  return _unknown_fields_.GetNoArena(\n"
949           "      &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
950           "}\n"
951           "\n"
952           "inline ::std::string* mutable_unknown_fields() {\n"
953           "  return _unknown_fields_.MutableNoArena(\n"
954           "      &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
955           "}\n"
956           "\n");
957       }
958     }
959   }
960 
961   // N.B.: We exclude GetArena() when arena support is disabled, falling back on
962   // MessageLite's implementation which returns NULL rather than generating our
963   // own method which returns NULL, in order to reduce code size.
964   if (SupportsArenas(descriptor_)) {
965     // virtual method version of GetArenaNoVirtual(), required for generic dispatch given a
966     // MessageLite* (e.g., in RepeatedField::AddAllocated()).
967     printer->Print(
968         "inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }\n"
969         "inline void* GetMaybeArenaPointer() const {\n"
970         "  return MaybeArenaPtr();\n"
971         "}\n");
972   }
973 
974   // Only generate this member if it's not disabled.
975   if (HasDescriptorMethods(descriptor_->file(), options_) &&
976       !descriptor_->options().no_standard_descriptor_accessor()) {
977     printer->Print(vars,
978       "static const ::google::protobuf::Descriptor* descriptor();\n");
979   }
980 
981   printer->Print(vars,
982     "static const $classname$& default_instance();\n"
983     "\n");
984 
985   // Generate enum values for every field in oneofs. One list is generated for
986   // each oneof with an additional *_NOT_SET value.
987   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
988     printer->Print(
989         "enum $camel_oneof_name$Case {\n",
990         "camel_oneof_name",
991         UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
992     printer->Indent();
993     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
994       printer->Print(
995           "k$field_name$ = $field_number$,\n",
996           "field_name",
997           UnderscoresToCamelCase(
998               descriptor_->oneof_decl(i)->field(j)->name(), true),
999           "field_number",
1000           SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
1001     }
1002     printer->Print(
1003         "$cap_oneof_name$_NOT_SET = 0,\n",
1004         "cap_oneof_name",
1005         ToUpper(descriptor_->oneof_decl(i)->name()));
1006     printer->Outdent();
1007     printer->Print(
1008         "};\n"
1009         "\n");
1010   }
1011 
1012   if (!StaticInitializersForced(descriptor_->file(), options_)) {
1013     printer->Print(vars,
1014       "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
1015       "// Returns the internal default instance pointer. This function can\n"
1016       "// return NULL thus should not be used by the user. This is intended\n"
1017       "// for Protobuf internal code. Please use default_instance() declared\n"
1018       "// above instead.\n"
1019       "static inline const $classname$* internal_default_instance() {\n"
1020       "  return default_instance_;\n"
1021       "}\n"
1022       "#endif\n"
1023       "\n");
1024   }
1025 
1026 
1027   if (SupportsArenas(descriptor_)) {
1028     printer->Print(vars,
1029       "void UnsafeArenaSwap($classname$* other);\n");
1030   }
1031 
1032   if (IsAnyMessage(descriptor_)) {
1033     printer->Print(vars,
1034       "// implements Any -----------------------------------------------\n"
1035       "\n"
1036       "void PackFrom(const ::google::protobuf::Message& message);\n"
1037       "void PackFrom(const ::google::protobuf::Message& message,\n"
1038       "              const ::std::string& type_url_prefix);\n"
1039       "bool UnpackTo(::google::protobuf::Message* message) const;\n"
1040       "template<typename T> bool Is() const {\n"
1041       "  return _any_metadata_.Is<T>();\n"
1042       "}\n"
1043       "\n");
1044   }
1045 
1046   printer->Print(vars,
1047     "void Swap($classname$* other);\n"
1048     "\n"
1049     "// implements Message ----------------------------------------------\n"
1050     "\n"
1051     "inline $classname$* New() const { return New(NULL); }\n"
1052     "\n"
1053     "$classname$* New(::google::protobuf::Arena* arena) const;\n");
1054 
1055   if (HasGeneratedMethods(descriptor_->file(), options_)) {
1056     if (HasDescriptorMethods(descriptor_->file(), options_)) {
1057       printer->Print(vars,
1058         "void CopyFrom(const ::google::protobuf::Message& from);\n"
1059         "void MergeFrom(const ::google::protobuf::Message& from);\n");
1060     } else {
1061       printer->Print(vars,
1062         "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
1063     }
1064 
1065     printer->Print(vars,
1066       "void CopyFrom(const $classname$& from);\n"
1067       "void MergeFrom(const $classname$& from);\n"
1068       "void Clear();\n"
1069       "bool IsInitialized() const;\n"
1070       "\n"
1071       "int ByteSize() const;\n"
1072       "bool MergePartialFromCodedStream(\n"
1073       "    ::google::protobuf::io::CodedInputStream* input);\n"
1074       "void SerializeWithCachedSizes(\n"
1075       "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
1076     // DiscardUnknownFields() is implemented in message.cc using reflections. We
1077     // need to implement this function in generated code for messages.
1078     if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
1079       printer->Print(
1080         "void DiscardUnknownFields();\n");
1081     }
1082     if (HasFastArraySerialization(descriptor_->file(), options_)) {
1083       printer->Print(
1084         "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n"
1085         "    bool deterministic, ::google::protobuf::uint8* output) const;\n"
1086         "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {\n"
1087         "  return InternalSerializeWithCachedSizesToArray(false, output);\n"
1088         "}\n");
1089     }
1090   }
1091 
1092   // Check all FieldDescriptors including those in oneofs to estimate
1093   // whether ::std::string is likely to be used, and depending on that
1094   // estimate, set uses_string_ to true or false.  That contols
1095   // whether to force initialization of empty_string_ in SharedCtor().
1096   // It's often advantageous to do so to keep "is empty_string_
1097   // inited?" code from appearing all over the place.
1098   vector<const FieldDescriptor*> descriptors;
1099   for (int i = 0; i < descriptor_->field_count(); i++) {
1100     descriptors.push_back(descriptor_->field(i));
1101   }
1102   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1103     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1104       descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
1105     }
1106   }
1107   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1108     const Descriptor* nested_type = descriptor_->nested_type(i);
1109     if (IsMapEntryMessage(nested_type)) {
1110       descriptors.push_back(nested_type->FindFieldByName("key"));
1111       descriptors.push_back(nested_type->FindFieldByName("value"));
1112     }
1113   }
1114   uses_string_ = false;
1115   if (PreserveUnknownFields(descriptor_) &&
1116       !UseUnknownFieldSet(descriptor_->file(), options_)) {
1117     uses_string_ = true;
1118   }
1119   for (int i = 0; i < descriptors.size(); i++) {
1120     const FieldDescriptor* field = descriptors[i];
1121     if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
1122       switch (field->options().ctype()) {
1123         default: uses_string_ = true; break;
1124       }
1125     }
1126   }
1127 
1128   printer->Print(
1129     "int GetCachedSize() const { return _cached_size_; }\n"
1130     "private:\n"
1131     "void SharedCtor();\n"
1132     "void SharedDtor();\n"
1133     "void SetCachedSize(int size) const;\n"
1134     "void InternalSwap($classname$* other);\n",
1135     "classname", classname_);
1136   if (SupportsArenas(descriptor_)) {
1137     printer->Print(
1138       "protected:\n"
1139       "explicit $classname$(::google::protobuf::Arena* arena);\n"
1140       "private:\n"
1141       "static void ArenaDtor(void* object);\n"
1142       "inline void RegisterArenaDtor(::google::protobuf::Arena* arena);\n",
1143       "classname", classname_);
1144   }
1145 
1146   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1147     printer->Print(
1148       "private:\n"
1149       "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
1150       "  return _internal_metadata_.arena();\n"
1151       "}\n"
1152       "inline void* MaybeArenaPtr() const {\n"
1153       "  return _internal_metadata_.raw_arena_ptr();\n"
1154       "}\n"
1155       "public:\n"
1156       "\n");
1157   } else {
1158     printer->Print(
1159       "private:\n"
1160       "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
1161       "  return _arena_ptr_;\n"
1162       "}\n"
1163       "inline ::google::protobuf::Arena* MaybeArenaPtr() const {\n"
1164       "  return _arena_ptr_;\n"
1165       "}\n"
1166       "public:\n"
1167       "\n");
1168   }
1169 
1170   if (HasDescriptorMethods(descriptor_->file(), options_)) {
1171     printer->Print(
1172       "::google::protobuf::Metadata GetMetadata() const;\n"
1173       "\n");
1174   } else {
1175     printer->Print(
1176       "::std::string GetTypeName() const;\n"
1177       "\n");
1178   }
1179 
1180   printer->Print(
1181     "// nested types ----------------------------------------------------\n"
1182     "\n");
1183 
1184   // Import all nested message classes into this class's scope with typedefs.
1185   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1186     const Descriptor* nested_type = descriptor_->nested_type(i);
1187     if (!IsMapEntryMessage(nested_type)) {
1188       printer->Print("typedef $nested_full_name$ $nested_name$;\n",
1189                      "nested_name", nested_type->name(),
1190                      "nested_full_name", ClassName(nested_type, false));
1191     }
1192   }
1193 
1194   if (descriptor_->nested_type_count() > 0) {
1195     printer->Print("\n");
1196   }
1197 
1198   // Import all nested enums and their values into this class's scope with
1199   // typedefs and constants.
1200   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1201     enum_generators_[i]->GenerateSymbolImports(printer);
1202     printer->Print("\n");
1203   }
1204 
1205   printer->Print(
1206     "// accessors -------------------------------------------------------\n"
1207     "\n");
1208 
1209   // Generate accessor methods for all fields.
1210   GenerateFieldAccessorDeclarations(printer);
1211 
1212   // Declare extension identifiers.
1213   for (int i = 0; i < descriptor_->extension_count(); i++) {
1214     extension_generators_[i]->GenerateDeclaration(printer);
1215   }
1216 
1217 
1218   printer->Print(
1219     "// @@protoc_insertion_point(class_scope:$full_name$)\n",
1220     "full_name", descriptor_->full_name());
1221 
1222   // Generate private members.
1223   printer->Outdent();
1224   printer->Print(" private:\n");
1225   printer->Indent();
1226 
1227 
1228   for (int i = 0; i < descriptor_->field_count(); i++) {
1229     if (!descriptor_->field(i)->is_repeated()) {
1230       // set_has_***() generated in all proto1/2 code and in oneofs (only) for
1231       // messages without true field presence.
1232       if (HasFieldPresence(descriptor_->file()) ||
1233           descriptor_->field(i)->containing_oneof()) {
1234         printer->Print(
1235           "inline void set_has_$name$();\n",
1236           "name", FieldName(descriptor_->field(i)));
1237       }
1238       // clear_has_***() generated only for non-oneof fields
1239       // in proto1/2.
1240       if (!descriptor_->field(i)->containing_oneof() &&
1241           HasFieldPresence(descriptor_->file())) {
1242         printer->Print(
1243           "inline void clear_has_$name$();\n",
1244           "name", FieldName(descriptor_->field(i)));
1245       }
1246     }
1247   }
1248   printer->Print("\n");
1249 
1250   // Generate oneof function declarations
1251   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1252     printer->Print(
1253         "inline bool has_$oneof_name$() const;\n"
1254         "void clear_$oneof_name$();\n"
1255         "inline void clear_has_$oneof_name$();\n\n",
1256         "oneof_name", descriptor_->oneof_decl(i)->name());
1257   }
1258 
1259   if (HasGeneratedMethods(descriptor_->file(), options_) &&
1260       !descriptor_->options().message_set_wire_format() &&
1261       num_required_fields_ > 1) {
1262     printer->Print(
1263         "// helper for ByteSize()\n"
1264         "int RequiredFieldsByteSizeFallback() const;\n\n");
1265   }
1266 
1267   // Prepare decls for _cached_size_ and _has_bits_.  Their position in the
1268   // output will be determined later.
1269 
1270   bool need_to_emit_cached_size = true;
1271   // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
1272   const string cached_size_decl = "mutable int _cached_size_;\n";
1273 
1274   // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
1275   size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
1276   if (descriptor_->field_count() == 0) {
1277     // Zero-size arrays aren't technically allowed, and MSVC in particular
1278     // doesn't like them.  We still need to declare these arrays to make
1279     // other code compile.  Since this is an uncommon case, we'll just declare
1280     // them with size 1 and waste some space.  Oh well.
1281     sizeof_has_bits = 4;
1282   }
1283   const string has_bits_decl = sizeof_has_bits == 0 ? "" :
1284       "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
1285 
1286 
1287   // To minimize padding, data members are divided into three sections:
1288   // (1) members assumed to align to 8 bytes
1289   // (2) members corresponding to message fields, re-ordered to optimize
1290   //     alignment.
1291   // (3) members assumed to align to 4 bytes.
1292 
1293   // Members assumed to align to 8 bytes:
1294 
1295   if (descriptor_->extension_range_count() > 0) {
1296     printer->Print(
1297       "::google::protobuf::internal::ExtensionSet _extensions_;\n"
1298       "\n");
1299   }
1300 
1301   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1302     printer->Print(
1303       "::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
1304   } else {
1305     printer->Print(
1306       "::google::protobuf::internal::ArenaStringPtr _unknown_fields_;\n"
1307       "::google::protobuf::Arena* _arena_ptr_;\n"
1308       "\n");
1309   }
1310 
1311   if (SupportsArenas(descriptor_)) {
1312     printer->Print(
1313       "friend class ::google::protobuf::Arena;\n"
1314       "typedef void InternalArenaConstructable_;\n"
1315       "typedef void DestructorSkippable_;\n");
1316   }
1317 
1318   if (HasFieldPresence(descriptor_->file())) {
1319     // _has_bits_ is frequently accessed, so to reduce code size and improve
1320     // speed, it should be close to the start of the object.  But, try not to
1321     // waste space:_has_bits_ by itself always makes sense if its size is a
1322     // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
1323     // will work well.
1324     printer->Print(has_bits_decl.c_str());
1325     if ((sizeof_has_bits % 8) != 0) {
1326       printer->Print(cached_size_decl.c_str());
1327       need_to_emit_cached_size = false;
1328     }
1329   } else {
1330     // Without field presence, we need another way to disambiguate the default
1331     // instance, because the default instance's submessage fields (if any) store
1332     // pointers to the default instances of the submessages even when they
1333     // aren't present. Alternatives to this approach might be to (i) use a
1334     // tagged pointer on all message fields, setting a tag bit for "not really
1335     // present, just default instance"; or (ii) comparing |this| against the
1336     // return value from GeneratedMessageFactory::GetPrototype() in all
1337     // has_$field$() calls. However, both of these options are much more
1338     // expensive (in code size and CPU overhead) than just checking a field in
1339     // the message. Long-term, the best solution would be to rearchitect the
1340     // default instance design not to store pointers to submessage default
1341     // instances, and have reflection get those some other way; but that change
1342     // would have too much impact on proto2.
1343     printer->Print(
1344       "bool _is_default_instance_;\n");
1345   }
1346 
1347   // Field members:
1348 
1349   // List fields which doesn't belong to any oneof
1350   vector<const FieldDescriptor*> fields;
1351   hash_map<string, int> fieldname_to_chunk;
1352   for (int i = 0; i < descriptor_->field_count(); i++) {
1353     if (!descriptor_->field(i)->containing_oneof()) {
1354       const FieldDescriptor* field = descriptor_->field(i);
1355       fields.push_back(field);
1356       fieldname_to_chunk[FieldName(field)] = i / 8;
1357     }
1358   }
1359   OptimizePadding(&fields);
1360   // Emit some private and static members
1361   runs_of_fields_ = vector< vector<string> >(1);
1362   for (int i = 0; i < fields.size(); ++i) {
1363     const FieldDescriptor* field = fields[i];
1364     const FieldGenerator& generator = field_generators_.get(field);
1365     generator.GenerateStaticMembers(printer);
1366     generator.GeneratePrivateMembers(printer);
1367     if (CanClearByZeroing(field)) {
1368       const string& fieldname = FieldName(field);
1369       if (!runs_of_fields_.back().empty() &&
1370           (fieldname_to_chunk[runs_of_fields_.back().back()] !=
1371            fieldname_to_chunk[fieldname])) {
1372         runs_of_fields_.push_back(vector<string>());
1373       }
1374       runs_of_fields_.back().push_back(fieldname);
1375     } else if (!runs_of_fields_.back().empty()) {
1376       runs_of_fields_.push_back(vector<string>());
1377     }
1378   }
1379 
1380   // For each oneof generate a union
1381   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1382     printer->Print(
1383         "union $camel_oneof_name$Union {\n"
1384         // explicit empty constructor is needed when union contains
1385         // ArenaStringPtr members for string fields.
1386         "  $camel_oneof_name$Union() {}\n",
1387         "camel_oneof_name",
1388         UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
1389     printer->Indent();
1390     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1391       field_generators_.get(descriptor_->oneof_decl(i)->
1392                             field(j)).GeneratePrivateMembers(printer);
1393     }
1394     printer->Outdent();
1395     printer->Print(
1396         "} $oneof_name$_;\n",
1397         "oneof_name", descriptor_->oneof_decl(i)->name());
1398     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1399       field_generators_.get(descriptor_->oneof_decl(i)->
1400                             field(j)).GenerateStaticMembers(printer);
1401     }
1402   }
1403 
1404   // Members assumed to align to 4 bytes:
1405 
1406   if (need_to_emit_cached_size) {
1407     printer->Print(cached_size_decl.c_str());
1408     need_to_emit_cached_size = false;
1409   }
1410 
1411   // Generate _oneof_case_.
1412   if (descriptor_->oneof_decl_count() > 0) {
1413     printer->Print(vars,
1414       "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
1415       "\n");
1416   }
1417 
1418   // Generate _any_metadata_ for the Any type.
1419   if (IsAnyMessage(descriptor_)) {
1420     printer->Print(vars,
1421       "::google::protobuf::internal::AnyMetadata _any_metadata_;\n");
1422   }
1423 
1424   // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
1425   // friends so that they can access private static variables like
1426   // default_instance_ and reflection_.
1427   PrintHandlingOptionalStaticInitializers(
1428       descriptor_->file(), options_, printer,
1429       // With static initializers.
1430       "friend void $dllexport_decl$ $adddescriptorsname$();\n",
1431       // Without.
1432       "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
1433       // Vars.
1434       "dllexport_decl", options_.dllexport_decl, "adddescriptorsname",
1435       GlobalAddDescriptorsName(descriptor_->file()->name()));
1436 
1437   printer->Print(
1438     "friend void $assigndescriptorsname$();\n"
1439     "friend void $shutdownfilename$();\n"
1440     "\n",
1441     "assigndescriptorsname",
1442       GlobalAssignDescriptorsName(descriptor_->file()->name()),
1443     "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
1444 
1445   printer->Print(
1446     "void InitAsDefaultInstance();\n"
1447     "static $classname$* default_instance_;\n",
1448     "classname", classname_);
1449 
1450   printer->Outdent();
1451   printer->Print(vars, "};");
1452   GOOGLE_DCHECK(!need_to_emit_cached_size);
1453 }
1454 
1455 void MessageGenerator::
GenerateDependentInlineMethods(io::Printer * printer)1456 GenerateDependentInlineMethods(io::Printer* printer) {
1457   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1458     // map entry message doesn't need inline methods. Since map entry message
1459     // cannot be a top level class, we just need to avoid calling
1460     // GenerateInlineMethods here.
1461     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1462     nested_generators_[i]->GenerateDependentInlineMethods(printer);
1463     printer->Print(kThinSeparator);
1464     printer->Print("\n");
1465   }
1466 
1467   GenerateDependentFieldAccessorDefinitions(printer);
1468 }
1469 
1470 void MessageGenerator::
GenerateInlineMethods(io::Printer * printer,bool is_inline)1471 GenerateInlineMethods(io::Printer* printer, bool is_inline) {
1472   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1473     // map entry message doesn't need inline methods. Since map entry message
1474     // cannot be a top level class, we just need to avoid calling
1475     // GenerateInlineMethods here.
1476     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1477     nested_generators_[i]->GenerateInlineMethods(printer, is_inline);
1478     printer->Print(kThinSeparator);
1479     printer->Print("\n");
1480   }
1481 
1482   GenerateFieldAccessorDefinitions(printer, is_inline);
1483 
1484   // Generate oneof_case() functions.
1485   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1486     map<string, string> vars;
1487     vars["class_name"] = classname_;
1488     vars["camel_oneof_name"] = UnderscoresToCamelCase(
1489         descriptor_->oneof_decl(i)->name(), true);
1490     vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
1491     vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
1492     vars["inline"] = is_inline ? "inline " : "";
1493     printer->Print(
1494         vars,
1495         "$inline$"
1496         "$class_name$::$camel_oneof_name$Case $class_name$::"
1497         "$oneof_name$_case() const {\n"
1498         "  return $class_name$::$camel_oneof_name$Case("
1499         "_oneof_case_[$oneof_index$]);\n"
1500         "}\n");
1501   }
1502 }
1503 
1504 void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer * printer)1505 GenerateDescriptorDeclarations(io::Printer* printer) {
1506   if (!IsMapEntryMessage(descriptor_)) {
1507     printer->Print(
1508       "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
1509       "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
1510       "  $name$_reflection_ = NULL;\n",
1511       "name", classname_);
1512   } else {
1513     printer->Print(
1514       "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
1515       "name", classname_);
1516   }
1517 
1518   // Generate oneof default instance for reflection usage.
1519   if (descriptor_->oneof_decl_count() > 0) {
1520     printer->Print("struct $name$OneofInstance {\n",
1521                    "name", classname_);
1522     for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1523       for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1524         const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1525         printer->Print("  ");
1526         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1527             (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
1528              EffectiveStringCType(field) != FieldOptions::STRING)) {
1529           printer->Print("const ");
1530         }
1531         field_generators_.get(field).GeneratePrivateMembers(printer);
1532       }
1533     }
1534 
1535     printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
1536                    "name", classname_);
1537   }
1538 
1539   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1540     nested_generators_[i]->GenerateDescriptorDeclarations(printer);
1541   }
1542 
1543   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1544     printer->Print(
1545       "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
1546       "name", ClassName(descriptor_->enum_type(i), false));
1547   }
1548 }
1549 
1550 void MessageGenerator::
GenerateDescriptorInitializer(io::Printer * printer,int index)1551 GenerateDescriptorInitializer(io::Printer* printer, int index) {
1552   // TODO(kenton):  Passing the index to this method is redundant; just use
1553   //   descriptor_->index() instead.
1554   map<string, string> vars;
1555   vars["classname"] = classname_;
1556   vars["index"] = SimpleItoa(index);
1557 
1558   // Obtain the descriptor from the parent's descriptor.
1559   if (descriptor_->containing_type() == NULL) {
1560     printer->Print(vars,
1561       "$classname$_descriptor_ = file->message_type($index$);\n");
1562   } else {
1563     vars["parent"] = ClassName(descriptor_->containing_type(), false);
1564     printer->Print(vars,
1565       "$classname$_descriptor_ = "
1566         "$parent$_descriptor_->nested_type($index$);\n");
1567   }
1568 
1569   if (IsMapEntryMessage(descriptor_)) return;
1570 
1571   // Generate the offsets.
1572   GenerateOffsets(printer);
1573 
1574   const bool pass_pool_and_factory = false;
1575   vars["fn"] = pass_pool_and_factory ?
1576       "new ::google::protobuf::internal::GeneratedMessageReflection" :
1577       "::google::protobuf::internal::GeneratedMessageReflection"
1578       "::NewGeneratedMessageReflection";
1579   // Construct the reflection object.
1580   printer->Print(vars,
1581     "$classname$_reflection_ =\n"
1582     "  $fn$(\n"
1583     "    $classname$_descriptor_,\n"
1584     "    $classname$::default_instance_,\n"
1585     "    $classname$_offsets_,\n");
1586   if (!HasFieldPresence(descriptor_->file())) {
1587     // If we don't have field presence, then _has_bits_ does not exist.
1588     printer->Print(vars,
1589     "    -1,\n");
1590   } else {
1591     printer->Print(vars,
1592     "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n");
1593   }
1594 
1595   // Unknown field offset: either points to the unknown field set if embedded
1596   // directly, or indicates that the unknown field set is stored as part of the
1597   // internal metadata if not.
1598   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1599     printer->Print(vars,
1600     "    -1,\n");
1601   } else {
1602     printer->Print(vars,
1603     "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1604       "$classname$, _unknown_fields_),\n");
1605   }
1606 
1607   if (descriptor_->extension_range_count() > 0) {
1608     printer->Print(vars,
1609       "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1610         "$classname$, _extensions_),\n");
1611   } else {
1612     // No extensions.
1613     printer->Print(vars,
1614       "    -1,\n");
1615   }
1616 
1617   if (descriptor_->oneof_decl_count() > 0) {
1618     printer->Print(vars,
1619     "    $classname$_default_oneof_instance_,\n"
1620     "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1621       "$classname$, _oneof_case_[0]),\n");
1622   }
1623 
1624   if (pass_pool_and_factory) {
1625     printer->Print(
1626         "    ::google::protobuf::DescriptorPool::generated_pool(),\n");
1627       printer->Print(vars,
1628                      "    ::google::protobuf::MessageFactory::generated_factory(),\n");
1629   }
1630 
1631   printer->Print(vars,
1632     "    sizeof($classname$),\n");
1633 
1634   // Arena offset: either an offset to the metadata struct that contains the
1635   // arena pointer and unknown field set (in a space-efficient way) if we use
1636   // that implementation strategy, or an offset directly to the arena pointer if
1637   // not (because e.g. we don't have an unknown field set).
1638   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1639     printer->Print(vars,
1640     "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1641     "$classname$, _internal_metadata_),\n");
1642   } else {
1643     printer->Print(vars,
1644     "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1645     "$classname$, _arena_),\n");
1646   }
1647 
1648   // is_default_instance_ offset.
1649   if (HasFieldPresence(descriptor_->file())) {
1650     printer->Print(vars,
1651     "    -1);\n");
1652   } else {
1653     printer->Print(vars,
1654     "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1655     "$classname$, _is_default_instance_));\n");
1656   }
1657 
1658   // Handle nested types.
1659   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1660     nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
1661   }
1662 
1663   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1664     enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
1665   }
1666 }
1667 
1668 void MessageGenerator::
GenerateTypeRegistrations(io::Printer * printer)1669 GenerateTypeRegistrations(io::Printer* printer) {
1670   // Register this message type with the message factory.
1671   if (!IsMapEntryMessage(descriptor_)) {
1672     printer->Print(
1673       "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1674       "    $classname$_descriptor_, &$classname$::default_instance());\n",
1675       "classname", classname_);
1676   }
1677   else {
1678     map<string, string> vars;
1679     CollectMapInfo(descriptor_, &vars);
1680     vars["classname"] = classname_;
1681 
1682     const FieldDescriptor* val = descriptor_->FindFieldByName("value");
1683     if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
1684         val->type() == FieldDescriptor::TYPE_ENUM) {
1685       const EnumValueDescriptor* default_value = val->default_value_enum();
1686       vars["default_enum_value"] = Int32ToString(default_value->number());
1687     } else {
1688       vars["default_enum_value"] = "0";
1689     }
1690 
1691     printer->Print(vars,
1692       "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1693       "      $classname$_descriptor_,\n"
1694       "      ::google::protobuf::internal::MapEntry<\n"
1695       "          $key$,\n"
1696       "          $val$,\n"
1697       "          $key_wire_type$,\n"
1698       "          $val_wire_type$,\n"
1699       "          $default_enum_value$>::CreateDefaultInstance(\n"
1700       "              $classname$_descriptor_));\n");
1701   }
1702 
1703   // Handle nested types.
1704   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1705     nested_generators_[i]->GenerateTypeRegistrations(printer);
1706   }
1707 }
1708 
1709 void MessageGenerator::
GenerateDefaultInstanceAllocator(io::Printer * printer)1710 GenerateDefaultInstanceAllocator(io::Printer* printer) {
1711   // Construct the default instances of all fields, as they will be used
1712   // when creating the default instance of the entire message.
1713   for (int i = 0; i < descriptor_->field_count(); i++) {
1714     field_generators_.get(descriptor_->field(i))
1715                      .GenerateDefaultInstanceAllocator(printer);
1716   }
1717 
1718   if (IsMapEntryMessage(descriptor_)) return;
1719 
1720   // Construct the default instance.  We can't call InitAsDefaultInstance() yet
1721   // because we need to make sure all default instances that this one might
1722   // depend on are constructed first.
1723   printer->Print(
1724     "$classname$::default_instance_ = new $classname$();\n",
1725     "classname", classname_);
1726 
1727   if ((descriptor_->oneof_decl_count() > 0) &&
1728       HasDescriptorMethods(descriptor_->file(), options_)) {
1729     printer->Print(
1730     "$classname$_default_oneof_instance_ = new $classname$OneofInstance();\n",
1731     "classname", classname_);
1732   }
1733 
1734   // Handle nested types.
1735   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1736     nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
1737   }
1738 
1739 }
1740 
1741 void MessageGenerator::
GenerateDefaultInstanceInitializer(io::Printer * printer)1742 GenerateDefaultInstanceInitializer(io::Printer* printer) {
1743   printer->Print(
1744     "$classname$::default_instance_->InitAsDefaultInstance();\n",
1745     "classname", classname_);
1746 
1747   // Register extensions.
1748   for (int i = 0; i < descriptor_->extension_count(); i++) {
1749     extension_generators_[i]->GenerateRegistration(printer);
1750   }
1751 
1752   // Handle nested types.
1753   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1754     // map entry message doesn't need to initialize default instance manually.
1755     // Since map entry message cannot be a top level class, we just need to
1756     // avoid calling DefaultInstanceInitializer here.
1757     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1758     nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
1759   }
1760 }
1761 
1762 void MessageGenerator::
GenerateShutdownCode(io::Printer * printer)1763 GenerateShutdownCode(io::Printer* printer) {
1764   printer->Print(
1765     "delete $classname$::default_instance_;\n",
1766     "classname", classname_);
1767 
1768   if (HasDescriptorMethods(descriptor_->file(), options_)) {
1769     if (descriptor_->oneof_decl_count() > 0) {
1770       printer->Print(
1771         "delete $classname$_default_oneof_instance_;\n",
1772         "classname", classname_);
1773     }
1774     printer->Print(
1775       "delete $classname$_reflection_;\n",
1776       "classname", classname_);
1777   }
1778 
1779   // Handle default instances of fields.
1780   for (int i = 0; i < descriptor_->field_count(); i++) {
1781     field_generators_.get(descriptor_->field(i))
1782                      .GenerateShutdownCode(printer);
1783   }
1784 
1785   // Handle nested types.
1786   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1787     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1788     nested_generators_[i]->GenerateShutdownCode(printer);
1789   }
1790 }
1791 
1792 void MessageGenerator::
GenerateClassMethods(io::Printer * printer)1793 GenerateClassMethods(io::Printer* printer) {
1794   // mutable_unknown_fields wrapper function for LazyStringOutputStream
1795   // callback.
1796   if (PreserveUnknownFields(descriptor_) &&
1797       !UseUnknownFieldSet(descriptor_->file(), options_)) {
1798     printer->Print(
1799         "static ::std::string* MutableUnknownFieldsFor$classname$(\n"
1800         "    $classname$* ptr) {\n"
1801         "  return ptr->mutable_unknown_fields();\n"
1802         "}\n"
1803         "\n",
1804         "classname", classname_);
1805   }
1806   if (IsAnyMessage(descriptor_)) {
1807     printer->Print(
1808       "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n"
1809       "  _any_metadata_.PackFrom(message);\n"
1810       "}\n"
1811       "\n"
1812       "void $classname$::PackFrom(const ::google::protobuf::Message& message,\n"
1813       "                           const ::std::string& type_url_prefix) {\n"
1814       "  _any_metadata_.PackFrom(message, type_url_prefix);\n"
1815       "}\n"
1816       "\n"
1817       "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n"
1818       "  return _any_metadata_.UnpackTo(message);\n"
1819       "}\n"
1820       "\n",
1821       "classname", classname_);
1822   }
1823 
1824   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1825     enum_generators_[i]->GenerateMethods(printer);
1826   }
1827 
1828   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1829     // map entry message doesn't need class methods. Since map entry message
1830     // cannot be a top level class, we just need to avoid calling
1831     // GenerateClassMethods here.
1832     if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1833     nested_generators_[i]->GenerateClassMethods(printer);
1834     printer->Print("\n");
1835     printer->Print(kThinSeparator);
1836     printer->Print("\n");
1837   }
1838 
1839   // Generate non-inline field definitions.
1840   for (int i = 0; i < descriptor_->field_count(); i++) {
1841     field_generators_.get(descriptor_->field(i))
1842                      .GenerateNonInlineAccessorDefinitions(printer);
1843   }
1844 
1845   // Generate field number constants.
1846   printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
1847   for (int i = 0; i < descriptor_->field_count(); i++) {
1848     const FieldDescriptor *field = descriptor_->field(i);
1849     printer->Print(
1850       "const int $classname$::$constant_name$;\n",
1851       "classname", ClassName(FieldScope(field), false),
1852       "constant_name", FieldConstantName(field));
1853   }
1854   printer->Print(
1855     "#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
1856     "\n");
1857 
1858   // Define extension identifiers.
1859   for (int i = 0; i < descriptor_->extension_count(); i++) {
1860     extension_generators_[i]->GenerateDefinition(printer);
1861   }
1862 
1863   GenerateStructors(printer);
1864   printer->Print("\n");
1865 
1866   if (descriptor_->oneof_decl_count() > 0) {
1867     GenerateOneofClear(printer);
1868     printer->Print("\n");
1869   }
1870 
1871   if (HasGeneratedMethods(descriptor_->file(), options_)) {
1872     GenerateClear(printer);
1873     printer->Print("\n");
1874 
1875     GenerateMergeFromCodedStream(printer);
1876     printer->Print("\n");
1877 
1878     GenerateSerializeWithCachedSizes(printer);
1879     printer->Print("\n");
1880 
1881     if (HasFastArraySerialization(descriptor_->file(), options_)) {
1882       GenerateSerializeWithCachedSizesToArray(printer);
1883       printer->Print("\n");
1884     }
1885 
1886     GenerateByteSize(printer);
1887     printer->Print("\n");
1888 
1889     GenerateMergeFrom(printer);
1890     printer->Print("\n");
1891 
1892     GenerateCopyFrom(printer);
1893     printer->Print("\n");
1894 
1895     GenerateIsInitialized(printer);
1896     printer->Print("\n");
1897   }
1898 
1899   GenerateSwap(printer);
1900   printer->Print("\n");
1901 
1902   if (HasDescriptorMethods(descriptor_->file(), options_)) {
1903     printer->Print(
1904       "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
1905       "  protobuf_AssignDescriptorsOnce();\n"
1906       "  ::google::protobuf::Metadata metadata;\n"
1907       "  metadata.descriptor = $classname$_descriptor_;\n"
1908       "  metadata.reflection = $classname$_reflection_;\n"
1909       "  return metadata;\n"
1910       "}\n"
1911       "\n",
1912       "classname", classname_);
1913   } else {
1914     printer->Print(
1915       "::std::string $classname$::GetTypeName() const {\n"
1916       "  return \"$type_name$\";\n"
1917       "}\n"
1918       "\n",
1919       "classname", classname_,
1920       "type_name", descriptor_->full_name());
1921   }
1922 
1923 }
1924 
1925 void MessageGenerator::
GenerateOffsets(io::Printer * printer)1926 GenerateOffsets(io::Printer* printer) {
1927   printer->Print("static const int $classname$_offsets_[$field_count$] = {\n",
1928                  "classname", classname_, "field_count",
1929                  SimpleItoa(std::max(1, descriptor_->field_count() +
1930                                             descriptor_->oneof_decl_count())));
1931   printer->Indent();
1932 
1933   for (int i = 0; i < descriptor_->field_count(); i++) {
1934     const FieldDescriptor* field = descriptor_->field(i);
1935     if (field->containing_oneof()) {
1936       printer->Print(
1937           "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
1938           "$classname$_default_oneof_instance_, $name$_),\n",
1939           "classname", classname_,
1940           "name", FieldName(field));
1941     } else {
1942       printer->Print(
1943           "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
1944                                                  "$name$_),\n",
1945           "classname", classname_,
1946           "name", FieldName(field));
1947     }
1948   }
1949 
1950   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1951     const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1952     printer->Print(
1953       "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
1954       "classname", classname_,
1955       "name", oneof->name());
1956   }
1957 
1958   printer->Outdent();
1959   printer->Print("};\n");
1960 }
1961 
1962 void MessageGenerator::
GenerateSharedConstructorCode(io::Printer * printer)1963 GenerateSharedConstructorCode(io::Printer* printer) {
1964   printer->Print(
1965     "void $classname$::SharedCtor() {\n",
1966     "classname", classname_);
1967   printer->Indent();
1968 
1969   if (!HasFieldPresence(descriptor_->file())) {
1970     printer->Print(
1971       "  _is_default_instance_ = false;\n");
1972   }
1973 
1974   printer->Print(StrCat(
1975       uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
1976       "_cached_size_ = 0;\n").c_str());
1977 
1978   if (PreserveUnknownFields(descriptor_) &&
1979       !UseUnknownFieldSet(descriptor_->file(), options_)) {
1980     printer->Print(
1981         "_unknown_fields_.UnsafeSetDefault(\n"
1982         "    &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
1983   }
1984 
1985   for (int i = 0; i < descriptor_->field_count(); i++) {
1986     if (!descriptor_->field(i)->containing_oneof()) {
1987       field_generators_.get(descriptor_->field(i))
1988           .GenerateConstructorCode(printer);
1989     }
1990   }
1991 
1992   if (HasFieldPresence(descriptor_->file())) {
1993     printer->Print(
1994       "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1995   }
1996 
1997   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1998     printer->Print(
1999         "clear_has_$oneof_name$();\n",
2000         "oneof_name", descriptor_->oneof_decl(i)->name());
2001   }
2002 
2003   printer->Outdent();
2004   printer->Print("}\n\n");
2005 }
2006 
2007 void MessageGenerator::
GenerateSharedDestructorCode(io::Printer * printer)2008 GenerateSharedDestructorCode(io::Printer* printer) {
2009   printer->Print(
2010     "void $classname$::SharedDtor() {\n",
2011     "classname", classname_);
2012   printer->Indent();
2013   if (SupportsArenas(descriptor_)) {
2014     // Do nothing when the message is allocated in an arena.
2015     printer->Print(
2016       "if (GetArenaNoVirtual() != NULL) {\n"
2017       "  return;\n"
2018       "}\n"
2019       "\n");
2020   }
2021 
2022   // Write the desctructor for _unknown_fields_ in lite runtime.
2023   if (PreserveUnknownFields(descriptor_) &&
2024       !UseUnknownFieldSet(descriptor_->file(), options_)) {
2025     if (SupportsArenas(descriptor_)) {
2026       printer->Print(
2027           "_unknown_fields_.Destroy(\n"
2028           "    &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
2029           "    GetArenaNoVirtual());\n");
2030     } else {
2031       printer->Print(
2032           "_unknown_fields_.DestroyNoArena(\n"
2033           "    &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
2034     }
2035   }
2036 
2037   // Write the destructors for each field except oneof members.
2038   for (int i = 0; i < descriptor_->field_count(); i++) {
2039     if (!descriptor_->field(i)->containing_oneof()) {
2040       field_generators_.get(descriptor_->field(i))
2041                        .GenerateDestructorCode(printer);
2042     }
2043   }
2044 
2045   // Generate code to destruct oneofs. Clearing should do the work.
2046   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2047     printer->Print(
2048         "if (has_$oneof_name$()) {\n"
2049         "  clear_$oneof_name$();\n"
2050         "}\n",
2051         "oneof_name", descriptor_->oneof_decl(i)->name());
2052   }
2053 
2054   PrintHandlingOptionalStaticInitializers(
2055       descriptor_->file(), options_, printer,
2056       // With static initializers.
2057       "if (this != default_instance_) {\n",
2058       // Without.
2059       "if (this != &default_instance()) {\n");
2060 
2061   // We need to delete all embedded messages.
2062   // TODO(kenton):  If we make unset messages point at default instances
2063   //   instead of NULL, then it would make sense to move this code into
2064   //   MessageFieldGenerator::GenerateDestructorCode().
2065   for (int i = 0; i < descriptor_->field_count(); i++) {
2066     const FieldDescriptor* field = descriptor_->field(i);
2067 
2068     if (!field->is_repeated() &&
2069         field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2070       // Skip oneof members
2071       if (!field->containing_oneof()) {
2072         printer->Print(
2073             "  delete $name$_;\n",
2074             "name", FieldName(field));
2075       }
2076     }
2077   }
2078 
2079   printer->Outdent();
2080   printer->Print(
2081     "  }\n"
2082     "}\n"
2083     "\n");
2084 }
2085 
2086 void MessageGenerator::
GenerateArenaDestructorCode(io::Printer * printer)2087 GenerateArenaDestructorCode(io::Printer* printer) {
2088   // Generate the ArenaDtor() method. Track whether any fields actually produced
2089   // code that needs to be called.
2090   printer->Print(
2091       "void $classname$::ArenaDtor(void* object) {\n",
2092       "classname", classname_);
2093   printer->Indent();
2094 
2095   // This code is placed inside a static method, rather than an ordinary one,
2096   // since that simplifies Arena's destructor list (ordinary function pointers
2097   // rather than member function pointers). _this is the object being
2098   // destructed.
2099   printer->Print(
2100       "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
2101       // avoid an "unused variable" warning in case no fields have dtor code.
2102       "(void)_this;\n",
2103       "classname", classname_);
2104 
2105   bool need_registration = false;
2106   for (int i = 0; i < descriptor_->field_count(); i++) {
2107     if (field_generators_.get(descriptor_->field(i))
2108                          .GenerateArenaDestructorCode(printer)) {
2109       need_registration = true;
2110     }
2111   }
2112   printer->Outdent();
2113   printer->Print(
2114       "}\n");
2115 
2116   if (need_registration) {
2117     printer->Print(
2118         "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
2119         "  if (arena != NULL) {\n"
2120         "    arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
2121         "  }\n"
2122         "}\n",
2123         "classname", classname_);
2124   } else {
2125     printer->Print(
2126         "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
2127         "}\n",
2128         "classname", classname_);
2129   }
2130 }
2131 
2132 void MessageGenerator::
GenerateStructors(io::Printer * printer)2133 GenerateStructors(io::Printer* printer) {
2134   string superclass;
2135   if (use_dependent_base_) {
2136     superclass =
2137         DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
2138   } else {
2139     superclass = SuperClassName(descriptor_, options_);
2140   }
2141   string initializer_with_arena = superclass + "()";
2142 
2143   if (descriptor_->extension_range_count() > 0) {
2144     initializer_with_arena += ",\n  _extensions_(arena)";
2145   }
2146 
2147   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2148     initializer_with_arena += ",\n  _internal_metadata_(arena)";
2149   } else {
2150     initializer_with_arena += ",\n  _arena_ptr_(arena)";
2151   }
2152 
2153   // Initialize member variables with arena constructor.
2154   for (int i = 0; i < descriptor_->field_count(); i++) {
2155     bool has_arena_constructor = descriptor_->field(i)->is_repeated();
2156     if (has_arena_constructor) {
2157       initializer_with_arena += string(",\n  ") +
2158           FieldName(descriptor_->field(i)) + string("_(arena)");
2159     }
2160   }
2161 
2162   if (IsAnyMessage(descriptor_)) {
2163     initializer_with_arena += ",\n  _any_metadata_(&type_url, &value_)";
2164   }
2165 
2166   string initializer_null;
2167   initializer_null = (UseUnknownFieldSet(descriptor_->file(), options_) ?
2168     ", _internal_metadata_(NULL)" : ", _arena_ptr_(NULL)");
2169   if (IsAnyMessage(descriptor_)) {
2170     initializer_null += ", _any_metadata_(&type_url_, &value_)";
2171   }
2172 
2173   printer->Print(
2174       "$classname$::$classname$()\n"
2175       "  : $superclass$()$initializer$ {\n"
2176       "  SharedCtor();\n"
2177       "  // @@protoc_insertion_point(constructor:$full_name$)\n"
2178       "}\n",
2179       "classname", classname_,
2180       "superclass", superclass,
2181       "full_name", descriptor_->full_name(),
2182       "initializer", initializer_null);
2183 
2184   if (SupportsArenas(descriptor_)) {
2185     printer->Print(
2186         "\n"
2187         "$classname$::$classname$(::google::protobuf::Arena* arena)\n"
2188         "  : $initializer$ {\n"
2189         "  SharedCtor();\n"
2190         "  RegisterArenaDtor(arena);\n"
2191         "  // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
2192         "}\n",
2193         "initializer", initializer_with_arena,
2194         "classname", classname_,
2195         "superclass", superclass,
2196         "full_name", descriptor_->full_name());
2197   }
2198 
2199   printer->Print(
2200     "\n"
2201     "void $classname$::InitAsDefaultInstance() {\n",
2202     "classname", classname_);
2203 
2204   if (!HasFieldPresence(descriptor_->file())) {
2205     printer->Print(
2206       "  _is_default_instance_ = true;\n");
2207   }
2208 
2209   // The default instance needs all of its embedded message pointers
2210   // cross-linked to other default instances.  We can't do this initialization
2211   // in the constructor because some other default instances may not have been
2212   // constructed yet at that time.
2213   // TODO(kenton):  Maybe all message fields (even for non-default messages)
2214   //   should be initialized to point at default instances rather than NULL?
2215   for (int i = 0; i < descriptor_->field_count(); i++) {
2216     const FieldDescriptor* field = descriptor_->field(i);
2217 
2218     if (!field->is_repeated() &&
2219         field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
2220         (field->containing_oneof() == NULL ||
2221          HasDescriptorMethods(descriptor_->file(), options_))) {
2222       string name;
2223       if (field->containing_oneof()) {
2224         name = classname_ + "_default_oneof_instance_->";
2225       }
2226       name += FieldName(field);
2227       PrintHandlingOptionalStaticInitializers(
2228           descriptor_->file(), options_, printer,
2229           // With static initializers.
2230           "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
2231           // Without.
2232           "  $name$_ = const_cast< $type$*>(\n"
2233           "      $type$::internal_default_instance());\n",
2234           // Vars.
2235           "name", name, "type", FieldMessageTypeName(field));
2236     } else if (field->containing_oneof() &&
2237                HasDescriptorMethods(descriptor_->file(), options_)) {
2238       field_generators_.get(descriptor_->field(i))
2239           .GenerateConstructorCode(printer);
2240     }
2241   }
2242   printer->Print(
2243     "}\n"
2244     "\n");
2245 
2246   // Generate the copy constructor.
2247   printer->Print(
2248     "$classname$::$classname$(const $classname$& from)\n"
2249     "  : $superclass$()",
2250     "classname", classname_,
2251     "superclass", superclass,
2252     "full_name", descriptor_->full_name());
2253   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2254     printer->Print(
2255         ",\n    _internal_metadata_(NULL)");
2256   } else if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
2257     printer->Print(",\n    _arena_ptr_(NULL)");
2258   }
2259   if (IsAnyMessage(descriptor_)) {
2260     printer->Print(",\n    _any_metadata_(&type_url_, &value_)");
2261   }
2262   printer->Print(" {\n");
2263   printer->Print(
2264     "  SharedCtor();\n"
2265     "  MergeFrom(from);\n"
2266     "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
2267     "}\n"
2268     "\n",
2269     "classname", classname_,
2270     "superclass", superclass,
2271     "full_name", descriptor_->full_name());
2272 
2273   // Generate the shared constructor code.
2274   GenerateSharedConstructorCode(printer);
2275 
2276   // Generate the destructor.
2277   printer->Print(
2278     "$classname$::~$classname$() {\n"
2279     "  // @@protoc_insertion_point(destructor:$full_name$)\n"
2280     "  SharedDtor();\n"
2281     "}\n"
2282     "\n",
2283     "classname", classname_,
2284     "full_name", descriptor_->full_name());
2285 
2286   // Generate the shared destructor code.
2287   GenerateSharedDestructorCode(printer);
2288 
2289   // Generate the arena-specific destructor code.
2290   if (SupportsArenas(descriptor_)) {
2291     GenerateArenaDestructorCode(printer);
2292   }
2293 
2294   // Generate SetCachedSize.
2295   printer->Print(
2296     "void $classname$::SetCachedSize(int size) const {\n"
2297     "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
2298     "  _cached_size_ = size;\n"
2299     "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
2300     "}\n",
2301     "classname", classname_);
2302 
2303   // Only generate this member if it's not disabled.
2304   if (HasDescriptorMethods(descriptor_->file(), options_) &&
2305       !descriptor_->options().no_standard_descriptor_accessor()) {
2306     printer->Print(
2307       "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
2308       "  protobuf_AssignDescriptorsOnce();\n"
2309       "  return $classname$_descriptor_;\n"
2310       "}\n"
2311       "\n",
2312       "classname", classname_,
2313       "adddescriptorsname",
2314       GlobalAddDescriptorsName(descriptor_->file()->name()));
2315   }
2316 
2317   printer->Print(
2318     "const $classname$& $classname$::default_instance() {\n",
2319     "classname", classname_);
2320 
2321   PrintHandlingOptionalStaticInitializers(
2322       descriptor_->file(), options_, printer,
2323       // With static initializers.
2324       "  if (default_instance_ == NULL) $adddescriptorsname$();\n",
2325       // Without.
2326       "  $adddescriptorsname$();\n",
2327       // Vars.
2328       "adddescriptorsname",
2329       GlobalAddDescriptorsName(descriptor_->file()->name()));
2330 
2331   printer->Print(
2332     "  return *default_instance_;\n"
2333     "}\n"
2334     "\n"
2335     "$classname$* $classname$::default_instance_ = NULL;\n"
2336     "\n",
2337     "classname", classname_);
2338 
2339   if (SupportsArenas(descriptor_)) {
2340     printer->Print(
2341       "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n"
2342       "  return ::google::protobuf::Arena::CreateMessage<$classname$>(arena);\n"
2343       "}\n",
2344       "classname", classname_);
2345   } else {
2346     printer->Print(
2347       "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n"
2348       "  $classname$* n = new $classname$;\n"
2349       "  if (arena != NULL) {\n"
2350       "    arena->Own(n);\n"
2351       "  }\n"
2352       "  return n;\n"
2353       "}\n",
2354       "classname", classname_);
2355   }
2356 
2357 }
2358 
2359 // Return the number of bits set in n, a non-negative integer.
popcnt(uint32 n)2360 static int popcnt(uint32 n) {
2361   int result = 0;
2362   while (n != 0) {
2363     result += (n & 1);
2364     n = n / 2;
2365   }
2366   return result;
2367 }
2368 
2369 void MessageGenerator::
GenerateClear(io::Printer * printer)2370 GenerateClear(io::Printer* printer) {
2371   printer->Print(
2372       "void $classname$::Clear() {\n"
2373       "// @@protoc_insertion_point(message_clear_start:$full_name$)\n",
2374       "classname", classname_, "full_name", descriptor_->full_name());
2375   printer->Indent();
2376 
2377   // Step 1: Extensions
2378   if (descriptor_->extension_range_count() > 0) {
2379     printer->Print("_extensions_.Clear();\n");
2380   }
2381 
2382   // Step 2: Everything but extensions, repeateds, unions.
2383   // These are handled in chunks of 8.  The first chunk is
2384   // the non-extensions-non-repeateds-non-unions in
2385   //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
2386   // and the second chunk is the same for
2387   //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
2388   // etc.
2389   set<int> step2_indices;
2390   hash_map<string, int> fieldname_to_chunk;
2391   hash_map<int, string> memsets_for_chunk;
2392   hash_map<int, int> memset_field_count_for_chunk;
2393   hash_set<string> handled;  // fields that appear anywhere in memsets_for_chunk
2394   hash_map<int, uint32> fields_mask_for_chunk;
2395   for (int i = 0; i < descriptor_->field_count(); i++) {
2396     const FieldDescriptor* field = descriptor_->field(i);
2397     if (!field->is_repeated() && !field->containing_oneof()) {
2398       step2_indices.insert(i);
2399       int chunk = i / 8;
2400       fieldname_to_chunk[FieldName(field)] = chunk;
2401       fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
2402     }
2403   }
2404 
2405   // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
2406   // The generated code uses two macros to help it clear runs of fields:
2407   // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the
2408   // positions of two fields in the Message.
2409   // ZR_ zeroes a non-empty range of fields via memset.
2410   const char* macros =
2411       "#if defined(__clang__)\n"
2412       "#define ZR_HELPER_(f) \\\n"
2413       "  _Pragma(\"clang diagnostic push\") \\\n"
2414       "  _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
2415       "  __builtin_offsetof($classname$, f) \\\n"
2416       "  _Pragma(\"clang diagnostic pop\")\n"
2417       "#else\n"
2418       "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
2419       "  &reinterpret_cast<$classname$*>(16)->f)\n"
2420       "#endif\n\n"
2421       "#define ZR_(first, last) do {\\\n"
2422       "  ::memset(&first, 0,\\\n"
2423       "           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
2424       "} while (0)\n\n";
2425   for (int i = 0; i < runs_of_fields_.size(); i++) {
2426     const vector<string>& run = runs_of_fields_[i];
2427     if (run.size() < 2) continue;
2428     const string& first_field_name = run[0];
2429     const string& last_field_name = run.back();
2430     int chunk = fieldname_to_chunk[run[0]];
2431     memsets_for_chunk[chunk].append(
2432       "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
2433     for (int j = 0; j < run.size(); j++) {
2434       GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
2435       handled.insert(run[j]);
2436     }
2437     memset_field_count_for_chunk[chunk] += run.size();
2438   }
2439   const bool macros_are_needed = handled.size() > 0;
2440   if (macros_are_needed) {
2441     printer->Outdent();
2442     printer->Print(macros,
2443                    "classname", classname_);
2444     printer->Indent();
2445   }
2446   // Step 2b: Finish step 2, ignoring fields handled in step 2a.
2447   int last_index = -1;
2448   bool chunk_block_in_progress = false;
2449   for (int i = 0; i < descriptor_->field_count(); i++) {
2450     if (step2_indices.count(i) == 0) continue;
2451     const FieldDescriptor* field = descriptor_->field(i);
2452     const string fieldname = FieldName(field);
2453     if (i / 8 != last_index / 8 || last_index < 0) {
2454       // End previous chunk, if there was one.
2455       if (chunk_block_in_progress) {
2456         printer->Outdent();
2457         printer->Print("}\n");
2458         chunk_block_in_progress = false;
2459       }
2460       // Start chunk.
2461       const string& memsets = memsets_for_chunk[i / 8];
2462       uint32 mask = fields_mask_for_chunk[i / 8];
2463       int count = popcnt(mask);
2464       GOOGLE_DCHECK_GE(count, 1);
2465       if (count == 1 ||
2466           (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
2467         // No "if" here because the chunk is trivial.
2468       } else {
2469         if (HasFieldPresence(descriptor_->file())) {
2470           printer->Print(
2471             "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
2472             "index", SimpleItoa(i / 8 * 8),
2473             "mask", SimpleItoa(mask));
2474           printer->Indent();
2475           chunk_block_in_progress = true;
2476         }
2477       }
2478       printer->Print(memsets.c_str());
2479     }
2480     last_index = i;
2481     if (handled.count(fieldname) > 0) continue;
2482 
2483     // It's faster to just overwrite primitive types, but we should
2484     // only clear strings and messages if they were set.
2485     // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
2486     bool should_check_bit =
2487       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
2488       field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
2489 
2490     bool have_enclosing_if = false;
2491     if (should_check_bit &&
2492         // If no field presence, then always clear strings/messages as well.
2493         HasFieldPresence(descriptor_->file())) {
2494       printer->Print("if (has_$name$()) {\n", "name", fieldname);
2495       printer->Indent();
2496       have_enclosing_if = true;
2497     }
2498 
2499     if (use_dependent_base_ && IsFieldDependent(field)) {
2500       printer->Print("clear_$name$();\n", "name", fieldname);
2501     } else {
2502       field_generators_.get(field).GenerateClearingCode(printer);
2503     }
2504 
2505     if (have_enclosing_if) {
2506       printer->Outdent();
2507       printer->Print("}\n");
2508     }
2509   }
2510 
2511   if (chunk_block_in_progress) {
2512     printer->Outdent();
2513     printer->Print("}\n");
2514   }
2515   if (macros_are_needed) {
2516     printer->Outdent();
2517     printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n");
2518     printer->Indent();
2519   }
2520 
2521   // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
2522   for (int i = 0; i < descriptor_->field_count(); i++) {
2523     const FieldDescriptor* field = descriptor_->field(i);
2524 
2525     if (field->is_repeated()) {
2526       if (use_dependent_base_ && IsFieldDependent(field)) {
2527         printer->Print("clear_$name$();\n", "name", FieldName(field));
2528       } else {
2529         field_generators_.get(field).GenerateClearingCode(printer);
2530       }
2531     }
2532   }
2533 
2534   // Step 4: Unions.
2535   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2536     printer->Print(
2537         "clear_$oneof_name$();\n",
2538         "oneof_name", descriptor_->oneof_decl(i)->name());
2539   }
2540 
2541   if (HasFieldPresence(descriptor_->file())) {
2542     // Step 5: Everything else.
2543     printer->Print(
2544       "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
2545   }
2546 
2547   if (PreserveUnknownFields(descriptor_)) {
2548     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2549       printer->Print(
2550         "if (_internal_metadata_.have_unknown_fields()) {\n"
2551         "  mutable_unknown_fields()->Clear();\n"
2552         "}\n");
2553     } else {
2554       if (SupportsArenas(descriptor_)) {
2555         printer->Print(
2556           "_unknown_fields_.ClearToEmpty(\n"
2557           "    &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
2558           "    GetArenaNoVirtual());\n");
2559       } else {
2560         printer->Print(
2561           "_unknown_fields_.ClearToEmptyNoArena(\n"
2562           "    &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
2563       }
2564     }
2565   }
2566 
2567   printer->Outdent();
2568   printer->Print("}\n");
2569 }
2570 
2571 void MessageGenerator::
GenerateOneofClear(io::Printer * printer)2572 GenerateOneofClear(io::Printer* printer) {
2573   // Generated function clears the active field and union case (e.g. foo_case_).
2574   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2575     map<string, string> oneof_vars;
2576     oneof_vars["classname"] = classname_;
2577     oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
2578     oneof_vars["full_name"] = descriptor_->full_name();
2579     string message_class;
2580 
2581     printer->Print(oneof_vars,
2582                    "void $classname$::clear_$oneofname$() {\n"
2583                    "// @@protoc_insertion_point(one_of_clear_start:"
2584                    "$full_name$)\n");
2585     printer->Indent();
2586     printer->Print(oneof_vars,
2587         "switch($oneofname$_case()) {\n");
2588     printer->Indent();
2589     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2590       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2591       printer->Print(
2592           "case k$field_name$: {\n",
2593           "field_name", UnderscoresToCamelCase(field->name(), true));
2594       printer->Indent();
2595       // We clear only allocated objects in oneofs
2596       if (!IsStringOrMessage(field)) {
2597         printer->Print(
2598             "// No need to clear\n");
2599       } else {
2600         field_generators_.get(field).GenerateClearingCode(printer);
2601       }
2602       printer->Print(
2603           "break;\n");
2604       printer->Outdent();
2605       printer->Print(
2606           "}\n");
2607     }
2608     printer->Print(
2609         "case $cap_oneof_name$_NOT_SET: {\n"
2610         "  break;\n"
2611         "}\n",
2612         "cap_oneof_name",
2613         ToUpper(descriptor_->oneof_decl(i)->name()));
2614     printer->Outdent();
2615     printer->Print(
2616         "}\n"
2617         "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
2618         "oneof_index", SimpleItoa(i),
2619         "cap_oneof_name",
2620         ToUpper(descriptor_->oneof_decl(i)->name()));
2621     printer->Outdent();
2622     printer->Print(
2623         "}\n"
2624         "\n");
2625   }
2626 }
2627 
2628 void MessageGenerator::
GenerateSwap(io::Printer * printer)2629 GenerateSwap(io::Printer* printer) {
2630   if (SupportsArenas(descriptor_)) {
2631     // Generate the Swap member function. This is a lightweight wrapper around
2632     // UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory
2633     // ownership situation: swapping across arenas or between an arena and a
2634     // heap requires copying.
2635     printer->Print(
2636         "void $classname$::Swap($classname$* other) {\n"
2637         "  if (other == this) return;\n"
2638         "  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
2639         "    InternalSwap(other);\n"
2640         "  } else {\n"
2641         "    $classname$ temp;\n"
2642         "    temp.MergeFrom(*this);\n"
2643         "    CopyFrom(*other);\n"
2644         "    other->CopyFrom(temp);\n"
2645         "  }\n"
2646         "}\n"
2647         "void $classname$::UnsafeArenaSwap($classname$* other) {\n"
2648         "  if (other == this) return;\n"
2649         "  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
2650         "  InternalSwap(other);\n"
2651         "}\n",
2652         "classname", classname_);
2653   } else {
2654     printer->Print(
2655         "void $classname$::Swap($classname$* other) {\n"
2656         "  if (other == this) return;\n"
2657         "  InternalSwap(other);\n"
2658         "}\n",
2659         "classname", classname_);
2660   }
2661 
2662   // Generate the UnsafeArenaSwap member function.
2663   printer->Print("void $classname$::InternalSwap($classname$* other) {\n",
2664                  "classname", classname_);
2665   printer->Indent();
2666 
2667   if (HasGeneratedMethods(descriptor_->file(), options_)) {
2668     for (int i = 0; i < descriptor_->field_count(); i++) {
2669       const FieldDescriptor* field = descriptor_->field(i);
2670       field_generators_.get(field).GenerateSwappingCode(printer);
2671     }
2672 
2673     for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2674       printer->Print(
2675         "std::swap($oneof_name$_, other->$oneof_name$_);\n"
2676         "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
2677         "oneof_name", descriptor_->oneof_decl(i)->name(),
2678         "i", SimpleItoa(i));
2679     }
2680 
2681     if (HasFieldPresence(descriptor_->file())) {
2682       for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
2683         printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
2684                        "i", SimpleItoa(i));
2685       }
2686     }
2687 
2688     // Ignore PreserveUnknownFields here - always swap internal_metadata as it
2689     // may contain more than just unknown fields.
2690     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2691       printer->Print(
2692           "_internal_metadata_.Swap(&other->_internal_metadata_);\n");
2693     } else {
2694       printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
2695     }
2696 
2697     printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
2698     if (descriptor_->extension_range_count() > 0) {
2699       printer->Print("_extensions_.Swap(&other->_extensions_);\n");
2700     }
2701   } else {
2702     printer->Print("GetReflection()->Swap(this, other);");
2703   }
2704 
2705   printer->Outdent();
2706   printer->Print("}\n");
2707 }
2708 
2709 void MessageGenerator::
GenerateMergeFrom(io::Printer * printer)2710 GenerateMergeFrom(io::Printer* printer) {
2711   if (HasDescriptorMethods(descriptor_->file(), options_)) {
2712     // Generate the generalized MergeFrom (aka that which takes in the Message
2713     // base class as a parameter).
2714     printer->Print(
2715         "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
2716         "// @@protoc_insertion_point(generalized_merge_from_start:"
2717         "$full_name$)\n"
2718         "  if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
2719         "    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
2720         "  }\n",
2721         "classname", classname_, "full_name", descriptor_->full_name());
2722     printer->Indent();
2723 
2724     // Cast the message to the proper type. If we find that the message is
2725     // *not* of the proper type, we can still call Merge via the reflection
2726     // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
2727     // for each message.
2728     printer->Print(
2729       "const $classname$* source = \n"
2730       "    ::google::protobuf::internal::DynamicCastToGenerated<const $classname$>(\n"
2731       "        &from);\n"
2732       "if (source == NULL) {\n"
2733       "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
2734       "$full_name$)\n"
2735       "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
2736       "} else {\n"
2737       "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
2738       "$full_name$)\n"
2739       "  MergeFrom(*source);\n"
2740       "}\n",
2741       "classname", classname_, "full_name", descriptor_->full_name());
2742 
2743     printer->Outdent();
2744     printer->Print("}\n\n");
2745   } else {
2746     // Generate CheckTypeAndMergeFrom().
2747     printer->Print(
2748       "void $classname$::CheckTypeAndMergeFrom(\n"
2749       "    const ::google::protobuf::MessageLite& from) {\n"
2750       "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
2751       "}\n"
2752       "\n",
2753       "classname", classname_);
2754   }
2755 
2756   // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
2757   printer->Print(
2758       "void $classname$::MergeFrom(const $classname$& from) {\n"
2759       "// @@protoc_insertion_point(class_specific_merge_from_start:"
2760       "$full_name$)\n"
2761       "  if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
2762       "    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
2763       "  }\n",
2764       "classname", classname_, "full_name", descriptor_->full_name());
2765   printer->Indent();
2766 
2767   // Merge Repeated fields. These fields do not require a
2768   // check as we can simply iterate over them.
2769   for (int i = 0; i < descriptor_->field_count(); ++i) {
2770     const FieldDescriptor* field = descriptor_->field(i);
2771 
2772     if (field->is_repeated()) {
2773       field_generators_.get(field).GenerateMergingCode(printer);
2774     }
2775   }
2776 
2777   // Merge oneof fields. Oneof field requires oneof case check.
2778   for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
2779     printer->Print(
2780         "switch (from.$oneofname$_case()) {\n",
2781         "oneofname", descriptor_->oneof_decl(i)->name());
2782     printer->Indent();
2783     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2784       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2785       printer->Print(
2786           "case k$field_name$: {\n",
2787           "field_name", UnderscoresToCamelCase(field->name(), true));
2788       printer->Indent();
2789       field_generators_.get(field).GenerateMergingCode(printer);
2790       printer->Print(
2791           "break;\n");
2792       printer->Outdent();
2793       printer->Print(
2794           "}\n");
2795     }
2796     printer->Print(
2797         "case $cap_oneof_name$_NOT_SET: {\n"
2798         "  break;\n"
2799         "}\n",
2800         "cap_oneof_name",
2801         ToUpper(descriptor_->oneof_decl(i)->name()));
2802     printer->Outdent();
2803     printer->Print(
2804         "}\n");
2805   }
2806 
2807   // Merge Optional and Required fields (after a _has_bit check).
2808   int last_index = -1;
2809 
2810   for (int i = 0; i < descriptor_->field_count(); ++i) {
2811     const FieldDescriptor* field = descriptor_->field(i);
2812 
2813     if (!field->is_repeated() && !field->containing_oneof()) {
2814       if (HasFieldPresence(descriptor_->file())) {
2815         // See above in GenerateClear for an explanation of this.
2816         if (i / 8 != last_index / 8 || last_index < 0) {
2817           if (last_index >= 0) {
2818             printer->Outdent();
2819             printer->Print("}\n");
2820           }
2821           printer->Print(
2822             "if (from._has_bits_[$index$ / 32] & "
2823             "(0xffu << ($index$ % 32))) {\n",
2824             "index", SimpleItoa(field->index()));
2825           printer->Indent();
2826         }
2827       }
2828 
2829       last_index = i;
2830 
2831       bool have_enclosing_if = false;
2832       if (HasFieldPresence(descriptor_->file())) {
2833         printer->Print(
2834           "if (from.has_$name$()) {\n",
2835           "name", FieldName(field));
2836         printer->Indent();
2837         have_enclosing_if = true;
2838       } else {
2839         // Merge semantics without true field presence: primitive fields are
2840         // merged only if non-zero (numeric) or non-empty (string).
2841         have_enclosing_if = EmitFieldNonDefaultCondition(
2842             printer, "from.", field);
2843       }
2844 
2845       field_generators_.get(field).GenerateMergingCode(printer);
2846 
2847       if (have_enclosing_if) {
2848         printer->Outdent();
2849         printer->Print("}\n");
2850       }
2851     }
2852   }
2853 
2854   if (HasFieldPresence(descriptor_->file()) &&
2855       last_index >= 0) {
2856     printer->Outdent();
2857     printer->Print("}\n");
2858   }
2859 
2860   if (descriptor_->extension_range_count() > 0) {
2861     printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
2862   }
2863 
2864   if (PreserveUnknownFields(descriptor_)) {
2865     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2866       printer->Print(
2867         "if (from._internal_metadata_.have_unknown_fields()) {\n"
2868         "  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"
2869         "}\n");
2870     } else {
2871       printer->Print(
2872         "if (!from.unknown_fields().empty()) {\n"
2873         "  mutable_unknown_fields()->append(from.unknown_fields());\n"
2874         "}\n");
2875     }
2876   }
2877 
2878   printer->Outdent();
2879   printer->Print("}\n");
2880 }
2881 
2882 void MessageGenerator::
GenerateCopyFrom(io::Printer * printer)2883 GenerateCopyFrom(io::Printer* printer) {
2884   if (HasDescriptorMethods(descriptor_->file(), options_)) {
2885     // Generate the generalized CopyFrom (aka that which takes in the Message
2886     // base class as a parameter).
2887     printer->Print(
2888         "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n"
2889         "// @@protoc_insertion_point(generalized_copy_from_start:"
2890         "$full_name$)\n",
2891         "classname", classname_, "full_name", descriptor_->full_name());
2892     printer->Indent();
2893 
2894     printer->Print(
2895       "if (&from == this) return;\n"
2896       "Clear();\n"
2897       "MergeFrom(from);\n");
2898 
2899     printer->Outdent();
2900     printer->Print("}\n\n");
2901   }
2902 
2903   // Generate the class-specific CopyFrom.
2904   printer->Print(
2905       "void $classname$::CopyFrom(const $classname$& from) {\n"
2906       "// @@protoc_insertion_point(class_specific_copy_from_start:"
2907       "$full_name$)\n",
2908       "classname", classname_, "full_name", descriptor_->full_name());
2909   printer->Indent();
2910 
2911   printer->Print(
2912     "if (&from == this) return;\n"
2913     "Clear();\n"
2914     "MergeFrom(from);\n");
2915 
2916   printer->Outdent();
2917   printer->Print("}\n");
2918 }
2919 
2920 void MessageGenerator::
GenerateMergeFromCodedStream(io::Printer * printer)2921 GenerateMergeFromCodedStream(io::Printer* printer) {
2922   if (descriptor_->options().message_set_wire_format()) {
2923     // Special-case MessageSet.
2924     printer->Print(
2925       "bool $classname$::MergePartialFromCodedStream(\n"
2926       "    ::google::protobuf::io::CodedInputStream* input) {\n",
2927       "classname", classname_);
2928 
2929     PrintHandlingOptionalStaticInitializers(
2930         descriptor_->file(), options_, printer,
2931         // With static initializers.
2932         "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
2933         "                                      mutable_unknown_fields());\n",
2934         // Without.
2935         "  return _extensions_.ParseMessageSet(input, &default_instance(),\n"
2936         "                                      mutable_unknown_fields());\n",
2937         // Vars.
2938         "classname", classname_);
2939 
2940     printer->Print(
2941       "}\n");
2942     return;
2943   }
2944 
2945   printer->Print(
2946     "bool $classname$::MergePartialFromCodedStream(\n"
2947     "    ::google::protobuf::io::CodedInputStream* input) {\n"
2948     "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n"
2949     "  ::google::protobuf::uint32 tag;\n",
2950     "classname", classname_);
2951 
2952   if (PreserveUnknownFields(descriptor_) &&
2953       !UseUnknownFieldSet(descriptor_->file(), options_)) {
2954     // Use LazyStringOutputString to avoid initializing unknown fields string
2955     // unless it is actually needed. For the same reason, disable eager refresh
2956     // on the CodedOutputStream.
2957     printer->Print(
2958       "  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
2959       "      ::google::protobuf::internal::NewPermanentCallback(\n"
2960       "          &MutableUnknownFieldsFor$classname$, this));\n"
2961       "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
2962       "      &unknown_fields_string, false);\n",
2963       "classname", classname_);
2964   }
2965 
2966   printer->Print(
2967     "  // @@protoc_insertion_point(parse_start:$full_name$)\n",
2968     "full_name", descriptor_->full_name());
2969 
2970   printer->Indent();
2971   printer->Print("for (;;) {\n");
2972   printer->Indent();
2973 
2974   google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
2975       SortFieldsByNumber(descriptor_));
2976   uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
2977       WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
2978   const int kCutoff0 = 127;               // fits in 1-byte varint
2979   const int kCutoff1 = (127 << 7) + 127;  // fits in 2-byte varint
2980   printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
2981                  "input->ReadTagWithCutoff($max$);\n"
2982                  "tag = p.first;\n"
2983                  "if (!p.second) goto handle_unusual;\n",
2984                  "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
2985                                    (maxtag <= kCutoff1 ? kCutoff1 :
2986                                     maxtag)));
2987   if (descriptor_->field_count() > 0) {
2988     // We don't even want to print the switch() if we have no fields because
2989     // MSVC dislikes switch() statements that contain only a default value.
2990 
2991     // Note:  If we just switched on the tag rather than the field number, we
2992     // could avoid the need for the if() to check the wire type at the beginning
2993     // of each case.  However, this is actually a bit slower in practice as it
2994     // creates a jump table that is 8x larger and sparser, and meanwhile the
2995     // if()s are highly predictable.
2996     printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
2997                    "GetTagFieldNumber(tag)) {\n");
2998 
2999     printer->Indent();
3000 
3001     // Find repeated messages and groups now, to simplify what follows.
3002     hash_set<int> fields_with_parse_loop;
3003     for (int i = 0; i < descriptor_->field_count(); i++) {
3004       const FieldDescriptor* field = ordered_fields[i];
3005       if (field->is_repeated() &&
3006           (field->type() == FieldDescriptor::TYPE_MESSAGE ||
3007            field->type() == FieldDescriptor::TYPE_GROUP)) {
3008         fields_with_parse_loop.insert(i);
3009       }
3010     }
3011 
3012     // need_label is true if we generated "goto parse_$name$" while handling the
3013     // previous field.
3014     bool need_label = false;
3015     for (int i = 0; i < descriptor_->field_count(); i++) {
3016       const FieldDescriptor* field = ordered_fields[i];
3017       const bool loops = fields_with_parse_loop.count(i) > 0;
3018       const bool next_field_loops = fields_with_parse_loop.count(i + 1) > 0;
3019 
3020       PrintFieldComment(printer, field);
3021 
3022       printer->Print(
3023         "case $number$: {\n",
3024         "number", SimpleItoa(field->number()));
3025       printer->Indent();
3026       const FieldGenerator& field_generator = field_generators_.get(field);
3027 
3028       // Emit code to parse the common, expected case.
3029       printer->Print("if (tag == $commontag$) {\n",
3030                      "commontag", SimpleItoa(WireFormat::MakeTag(field)));
3031 
3032       if (need_label ||
3033           (field->is_repeated() && !field->is_packed() && !loops)) {
3034         printer->Print(
3035             " parse_$name$:\n",
3036             "name", field->name());
3037       }
3038       if (loops) {
3039         printer->Print(
3040           "  DO_(input->IncrementRecursionDepth());\n"
3041           " parse_loop_$name$:\n",
3042           "name", field->name());
3043       }
3044 
3045       printer->Indent();
3046       if (field->is_packed()) {
3047         field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
3048       } else {
3049         field_generator.GenerateMergeFromCodedStream(printer);
3050       }
3051       printer->Outdent();
3052 
3053       // Emit code to parse unexpectedly packed or unpacked values.
3054       if (field->is_packed()) {
3055         internal::WireFormatLite::WireType wiretype =
3056             WireFormat::WireTypeForFieldType(field->type());
3057         printer->Print("} else if (tag == $uncommontag$) {\n",
3058                        "uncommontag", SimpleItoa(
3059                            internal::WireFormatLite::MakeTag(
3060                                field->number(), wiretype)));
3061         printer->Indent();
3062         field_generator.GenerateMergeFromCodedStream(printer);
3063         printer->Outdent();
3064       } else if (field->is_packable() && !field->is_packed()) {
3065         internal::WireFormatLite::WireType wiretype =
3066             internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
3067         printer->Print("} else if (tag == $uncommontag$) {\n",
3068                        "uncommontag", SimpleItoa(
3069                            internal::WireFormatLite::MakeTag(
3070                                field->number(), wiretype)));
3071         printer->Indent();
3072         field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
3073         printer->Outdent();
3074       }
3075 
3076       printer->Print(
3077         "} else {\n"
3078         "  goto handle_unusual;\n"
3079         "}\n");
3080 
3081       // switch() is slow since it can't be predicted well.  Insert some if()s
3082       // here that attempt to predict the next tag.
3083       // For non-packed repeated fields, expect the same tag again.
3084       if (loops) {
3085         printer->Print(
3086           "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n",
3087           "tag", SimpleItoa(WireFormat::MakeTag(field)),
3088           "name", field->name());
3089       } else if (field->is_repeated() && !field->is_packed()) {
3090         printer->Print(
3091           "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
3092           "tag", SimpleItoa(WireFormat::MakeTag(field)),
3093           "name", field->name());
3094       }
3095 
3096       // Have we emitted "if (input->ExpectTag($next_tag$)) ..." yet?
3097       bool emitted_goto_next_tag = false;
3098 
3099       // For repeated messages/groups, we need to decrement recursion depth,
3100       // unless the next tag is also for a repeated message/group.
3101       if (loops) {
3102         if (next_field_loops) {
3103           const FieldDescriptor* next_field = ordered_fields[i + 1];
3104           printer->Print(
3105             "if (input->ExpectTag($next_tag$)) goto parse_loop_$next_name$;\n",
3106             "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
3107             "next_name", next_field->name());
3108           emitted_goto_next_tag = true;
3109         }
3110         printer->Print(
3111           "input->UnsafeDecrementRecursionDepth();\n");
3112       }
3113 
3114       // If there are more fields, expect the next one.
3115       need_label = false;
3116       if (!emitted_goto_next_tag) {
3117         if (i + 1 == descriptor_->field_count()) {
3118           // Expect EOF.
3119           // TODO(kenton):  Expect group end-tag?
3120           printer->Print(
3121             "if (input->ExpectAtEnd()) goto success;\n");
3122         } else {
3123           const FieldDescriptor* next_field = ordered_fields[i + 1];
3124           printer->Print(
3125             "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
3126             "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
3127             "next_name", next_field->name());
3128           need_label = true;
3129         }
3130       }
3131 
3132       printer->Print(
3133         "break;\n");
3134 
3135       printer->Outdent();
3136       printer->Print("}\n\n");
3137     }
3138 
3139     printer->Print("default: {\n");
3140     printer->Indent();
3141   }
3142 
3143   printer->Outdent();
3144   printer->Print("handle_unusual:\n");
3145   printer->Indent();
3146   // If tag is 0 or an end-group tag then this must be the end of the message.
3147   printer->Print(
3148     "if (tag == 0 ||\n"
3149     "    ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
3150     "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
3151     "  goto success;\n"
3152     "}\n");
3153 
3154   // Handle extension ranges.
3155   if (descriptor_->extension_range_count() > 0) {
3156     printer->Print(
3157       "if (");
3158     for (int i = 0; i < descriptor_->extension_range_count(); i++) {
3159       const Descriptor::ExtensionRange* range =
3160         descriptor_->extension_range(i);
3161       if (i > 0) printer->Print(" ||\n    ");
3162 
3163       uint32 start_tag = WireFormatLite::MakeTag(
3164         range->start, static_cast<WireFormatLite::WireType>(0));
3165       uint32 end_tag = WireFormatLite::MakeTag(
3166         range->end, static_cast<WireFormatLite::WireType>(0));
3167 
3168       if (range->end > FieldDescriptor::kMaxNumber) {
3169         printer->Print(
3170           "($start$u <= tag)",
3171           "start", SimpleItoa(start_tag));
3172       } else {
3173         printer->Print(
3174           "($start$u <= tag && tag < $end$u)",
3175           "start", SimpleItoa(start_tag),
3176           "end", SimpleItoa(end_tag));
3177       }
3178     }
3179     printer->Print(") {\n");
3180     if (PreserveUnknownFields(descriptor_)) {
3181       if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3182         PrintHandlingOptionalStaticInitializers(
3183             descriptor_->file(), options_, printer,
3184             // With static initializers.
3185             "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
3186             "                              mutable_unknown_fields()));\n",
3187             // Without.
3188             "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
3189             "                              mutable_unknown_fields()));\n");
3190       } else {
3191         PrintHandlingOptionalStaticInitializers(
3192             descriptor_->file(), options_, printer,
3193             // With static initializers.
3194             "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
3195             "                              &unknown_fields_stream));\n",
3196             // Without.
3197             "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
3198             "                              &unknown_fields_stream));\n");
3199       }
3200     } else {
3201       PrintHandlingOptionalStaticInitializers(
3202           descriptor_->file(), options_, printer,
3203           // With static initializers.
3204           "  DO_(_extensions_.ParseField(tag, input, default_instance_);\n",
3205           // Without.
3206           "  DO_(_extensions_.ParseField(tag, input, &default_instance());\n");
3207     }
3208     printer->Print(
3209       "  continue;\n"
3210       "}\n");
3211   }
3212 
3213   // We really don't recognize this tag.  Skip it.
3214   if (PreserveUnknownFields(descriptor_)) {
3215     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3216       printer->Print(
3217         "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
3218         "      input, tag, mutable_unknown_fields()));\n");
3219     } else {
3220       printer->Print(
3221         "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
3222         "    input, tag, &unknown_fields_stream));\n");
3223     }
3224   } else {
3225     printer->Print(
3226       "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
3227   }
3228 
3229   if (descriptor_->field_count() > 0) {
3230     printer->Print("break;\n");
3231     printer->Outdent();
3232     printer->Print("}\n");    // default:
3233     printer->Outdent();
3234     printer->Print("}\n");    // switch
3235   }
3236 
3237   printer->Outdent();
3238   printer->Outdent();
3239   printer->Print(
3240     "  }\n"                   // for (;;)
3241     "success:\n"
3242     "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
3243     "  return true;\n"
3244     "failure:\n"
3245     "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
3246     "  return false;\n"
3247     "#undef DO_\n"
3248     "}\n", "full_name", descriptor_->full_name());
3249 }
3250 
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field,bool to_array)3251 void MessageGenerator::GenerateSerializeOneField(
3252     io::Printer* printer, const FieldDescriptor* field, bool to_array) {
3253   PrintFieldComment(printer, field);
3254 
3255   bool have_enclosing_if = false;
3256   if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) {
3257     printer->Print(
3258       "if (has_$name$()) {\n",
3259       "name", FieldName(field));
3260     printer->Indent();
3261     have_enclosing_if = true;
3262   } else if (!HasFieldPresence(descriptor_->file())) {
3263     have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
3264   }
3265 
3266   if (to_array) {
3267     field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
3268         printer);
3269   } else {
3270     field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
3271   }
3272 
3273   if (have_enclosing_if) {
3274     printer->Outdent();
3275     printer->Print("}\n");
3276   }
3277   printer->Print("\n");
3278 }
3279 
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range,bool to_array)3280 void MessageGenerator::GenerateSerializeOneExtensionRange(
3281     io::Printer* printer, const Descriptor::ExtensionRange* range,
3282     bool to_array) {
3283   map<string, string> vars;
3284   vars["start"] = SimpleItoa(range->start);
3285   vars["end"] = SimpleItoa(range->end);
3286   printer->Print(vars,
3287     "// Extension range [$start$, $end$)\n");
3288   if (to_array) {
3289     printer->Print(vars,
3290       "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n"
3291       "    $start$, $end$, false, target);\n\n");
3292   } else {
3293     printer->Print(vars,
3294       "_extensions_.SerializeWithCachedSizes(\n"
3295       "    $start$, $end$, output);\n\n");
3296   }
3297 }
3298 
3299 void MessageGenerator::
GenerateSerializeWithCachedSizes(io::Printer * printer)3300 GenerateSerializeWithCachedSizes(io::Printer* printer) {
3301   if (descriptor_->options().message_set_wire_format()) {
3302     // Special-case MessageSet.
3303     printer->Print(
3304       "void $classname$::SerializeWithCachedSizes(\n"
3305       "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
3306       "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
3307       "classname", classname_);
3308     GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3309     printer->Print(
3310       "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
3311       "      unknown_fields(), output);\n");
3312     printer->Print(
3313       "}\n");
3314     return;
3315   }
3316 
3317   printer->Print(
3318     "void $classname$::SerializeWithCachedSizes(\n"
3319     "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
3320     "classname", classname_);
3321   printer->Indent();
3322 
3323   printer->Print(
3324     "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
3325     "full_name", descriptor_->full_name());
3326 
3327   GenerateSerializeWithCachedSizesBody(printer, false);
3328 
3329   printer->Print(
3330     "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
3331     "full_name", descriptor_->full_name());
3332 
3333   printer->Outdent();
3334   printer->Print(
3335     "}\n");
3336 }
3337 
3338 void MessageGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer * printer)3339 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
3340   if (descriptor_->options().message_set_wire_format()) {
3341     // Special-case MessageSet.
3342     printer->Print(
3343       "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n"
3344       "    bool deterministic, ::google::protobuf::uint8* target) const {\n"
3345       "  target = _extensions_."
3346       "InternalSerializeMessageSetWithCachedSizesToArray(\n"
3347       "               deterministic, target);\n",
3348       "classname", classname_);
3349     GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3350     printer->Print(
3351       "  target = ::google::protobuf::internal::WireFormat::\n"
3352       "             SerializeUnknownMessageSetItemsToArray(\n"
3353       "               unknown_fields(), target);\n");
3354     printer->Print(
3355       "  return target;\n"
3356       "}\n");
3357     return;
3358   }
3359 
3360   printer->Print(
3361     "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n"
3362     "    bool deterministic, ::google::protobuf::uint8* target) const {\n",
3363     "classname", classname_);
3364   printer->Indent();
3365 
3366   printer->Print(
3367     "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
3368     "full_name", descriptor_->full_name());
3369 
3370   GenerateSerializeWithCachedSizesBody(printer, true);
3371 
3372   printer->Print(
3373     "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
3374     "full_name", descriptor_->full_name());
3375 
3376   printer->Outdent();
3377   printer->Print(
3378     "  return target;\n"
3379     "}\n");
3380 }
3381 
3382 void MessageGenerator::
GenerateSerializeWithCachedSizesBody(io::Printer * printer,bool to_array)3383 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
3384   google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
3385       SortFieldsByNumber(descriptor_));
3386 
3387   vector<const Descriptor::ExtensionRange*> sorted_extensions;
3388   for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
3389     sorted_extensions.push_back(descriptor_->extension_range(i));
3390   }
3391   std::sort(sorted_extensions.begin(), sorted_extensions.end(),
3392             ExtensionRangeSorter());
3393 
3394   // Merge the fields and the extension ranges, both sorted by field number.
3395   int i, j;
3396   for (i = 0, j = 0;
3397        i < descriptor_->field_count() || j < sorted_extensions.size();
3398        ) {
3399     if (i == descriptor_->field_count()) {
3400       GenerateSerializeOneExtensionRange(printer,
3401                                          sorted_extensions[j++],
3402                                          to_array);
3403     } else if (j == sorted_extensions.size()) {
3404       GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
3405     } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
3406       GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
3407     } else {
3408       GenerateSerializeOneExtensionRange(printer,
3409                                          sorted_extensions[j++],
3410                                          to_array);
3411     }
3412   }
3413 
3414   if (PreserveUnknownFields(descriptor_)) {
3415     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3416       printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n");
3417       printer->Indent();
3418       if (to_array) {
3419         printer->Print(
3420           "target = "
3421               "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
3422           "    unknown_fields(), target);\n");
3423       } else {
3424         printer->Print(
3425           "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
3426           "    unknown_fields(), output);\n");
3427       }
3428       printer->Outdent();
3429 
3430       printer->Print(
3431         "}\n");
3432     } else {
3433       printer->Print(
3434         "output->WriteRaw(unknown_fields().data(),\n"
3435         "                 static_cast<int>(unknown_fields().size()));\n");
3436     }
3437   }
3438 }
3439 
RequiredFieldsBitMask(const Descriptor * desc)3440 static vector<uint32> RequiredFieldsBitMask(const Descriptor* desc) {
3441   vector<uint32> result;
3442   uint32 mask = 0;
3443   for (int i = 0; i < desc->field_count(); i++) {
3444     if (i > 0 && i % 32 == 0) {
3445       result.push_back(mask);
3446       mask = 0;
3447     }
3448     if (desc->field(i)->is_required()) {
3449       mask |= (1 << (i & 31));
3450     }
3451   }
3452   if (mask != 0) {
3453     result.push_back(mask);
3454   }
3455   return result;
3456 }
3457 
3458 // Create an expression that evaluates to
3459 //  "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
3460 // masks is allowed to be shorter than _has_bits_, but at least one element of
3461 // masks must be non-zero.
ConditionalToCheckBitmasks(const vector<uint32> & masks)3462 static string ConditionalToCheckBitmasks(const vector<uint32>& masks) {
3463   vector<string> parts;
3464   for (int i = 0; i < masks.size(); i++) {
3465     if (masks[i] == 0) continue;
3466     string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
3467     // Each xor evaluates to 0 if the expected bits are present.
3468     parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
3469   }
3470   GOOGLE_CHECK(!parts.empty());
3471   // If we have multiple parts, each expected to be 0, then bitwise-or them.
3472   string result = parts.size() == 1 ? parts[0] :
3473       StrCat("(", Join(parts, "\n       | "), ")");
3474   return result + " == 0";
3475 }
3476 
3477 void MessageGenerator::
GenerateByteSize(io::Printer * printer)3478 GenerateByteSize(io::Printer* printer) {
3479   if (descriptor_->options().message_set_wire_format()) {
3480     // Special-case MessageSet.
3481     printer->Print(
3482         "int $classname$::ByteSize() const {\n"
3483         "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
3484         "  int total_size = _extensions_.MessageSetByteSize();\n",
3485         "classname", classname_, "full_name", descriptor_->full_name());
3486     GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3487     printer->Print(
3488       "if (_internal_metadata_.have_unknown_fields()) {\n"
3489       "  total_size += ::google::protobuf::internal::WireFormat::\n"
3490       "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n"
3491       "}\n");
3492     printer->Print(
3493       "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
3494       "  _cached_size_ = total_size;\n"
3495       "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
3496       "  return total_size;\n"
3497       "}\n");
3498     return;
3499   }
3500 
3501   if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
3502     // Emit a function (rarely used, we hope) that handles the required fields
3503     // by checking for each one individually.
3504     printer->Print(
3505         "int $classname$::RequiredFieldsByteSizeFallback() const {\n"
3506         "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
3507         "$full_name$)\n",
3508         "classname", classname_, "full_name", descriptor_->full_name());
3509     printer->Indent();
3510     printer->Print("int total_size = 0;\n");
3511     for (int i = 0; i < descriptor_->field_count(); i++) {
3512       const FieldDescriptor* field = descriptor_->field(i);
3513       if (field->is_required()) {
3514         printer->Print("\n"
3515                        "if (has_$name$()) {\n",
3516                        "name", FieldName(field));
3517         printer->Indent();
3518         PrintFieldComment(printer, field);
3519         field_generators_.get(field).GenerateByteSize(printer);
3520         printer->Outdent();
3521         printer->Print("}\n");
3522       }
3523     }
3524     printer->Print("\n"
3525                    "return total_size;\n");
3526     printer->Outdent();
3527     printer->Print("}\n");
3528   }
3529 
3530   printer->Print(
3531       "int $classname$::ByteSize() const {\n"
3532       "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n",
3533       "classname", classname_, "full_name", descriptor_->full_name());
3534   printer->Indent();
3535   printer->Print(
3536     "int total_size = 0;\n"
3537     "\n");
3538 
3539   // Handle required fields (if any).  We expect all of them to be
3540   // present, so emit one conditional that checks for that.  If they are all
3541   // present then the fast path executes; otherwise the slow path executes.
3542   if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
3543     // The fast path works if all required fields are present.
3544     vector<uint32> masks_for_has_bits = RequiredFieldsBitMask(descriptor_);
3545     printer->Print((string("if (") +
3546                     ConditionalToCheckBitmasks(masks_for_has_bits) +
3547                     ") {  // All required fields are present.\n").c_str());
3548     printer->Indent();
3549     for (int i = 0; i < descriptor_->field_count(); i++) {
3550       const FieldDescriptor* field = descriptor_->field(i);
3551       if (!field->is_required()) continue;
3552       PrintFieldComment(printer, field);
3553       field_generators_.get(field).GenerateByteSize(printer);
3554       printer->Print("\n");
3555     }
3556     printer->Outdent();
3557     printer->Print("} else {\n"  // the slow path
3558                    "  total_size += RequiredFieldsByteSizeFallback();\n"
3559                    "}\n");
3560   } else {
3561     // num_required_fields_ <= 1: no need to be tricky
3562     for (int i = 0; i < descriptor_->field_count(); i++) {
3563       const FieldDescriptor* field = descriptor_->field(i);
3564       if (!field->is_required()) continue;
3565       PrintFieldComment(printer, field);
3566       printer->Print("if (has_$name$()) {\n",
3567                      "name", FieldName(field));
3568       printer->Indent();
3569       field_generators_.get(field).GenerateByteSize(printer);
3570       printer->Outdent();
3571       printer->Print("}\n");
3572     }
3573   }
3574 
3575   // Handle optional fields (worry below about repeateds, oneofs, etc.).
3576   // These are handled in chunks of 8.  The first chunk is
3577   // the non-requireds-non-repeateds-non-unions-non-extensions in
3578   //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
3579   // and the second chunk is the same for
3580   //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
3581   // etc.
3582   hash_map<int, uint32> fields_mask_for_chunk;
3583   for (int i = 0; i < descriptor_->field_count(); i++) {
3584     const FieldDescriptor* field = descriptor_->field(i);
3585     if (!field->is_required() && !field->is_repeated() &&
3586         !field->containing_oneof()) {
3587       fields_mask_for_chunk[i / 8] |= static_cast<uint32>(1) << (i % 32);
3588     }
3589   }
3590 
3591   int last_index = -1;
3592   bool chunk_block_in_progress = false;
3593   for (int i = 0; i < descriptor_->field_count(); i++) {
3594     const FieldDescriptor* field = descriptor_->field(i);
3595     if (!field->is_required() && !field->is_repeated() &&
3596         !field->containing_oneof()) {
3597       // See above in GenerateClear for an explanation of this.
3598       // TODO(kenton):  Share code?  Unclear how to do so without
3599       //   over-engineering.
3600       if (i / 8 != last_index / 8 || last_index < 0) {
3601         // End previous chunk, if there was one.
3602         if (chunk_block_in_progress) {
3603           printer->Outdent();
3604           printer->Print("}\n");
3605           chunk_block_in_progress = false;
3606         }
3607         // Start chunk.
3608         uint32 mask = fields_mask_for_chunk[i / 8];
3609         int count = popcnt(mask);
3610         GOOGLE_DCHECK_GE(count, 1);
3611         if (count == 1) {
3612           // No "if" here because the chunk is trivial.
3613         } else {
3614           if (HasFieldPresence(descriptor_->file())) {
3615             printer->Print(
3616               "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
3617               "index", SimpleItoa(i),
3618               "mask", SimpleItoa(mask));
3619             printer->Indent();
3620             chunk_block_in_progress = true;
3621           }
3622         }
3623       }
3624       last_index = i;
3625 
3626       PrintFieldComment(printer, field);
3627 
3628       bool have_enclosing_if = false;
3629       if (HasFieldPresence(descriptor_->file())) {
3630         printer->Print(
3631           "if (has_$name$()) {\n",
3632           "name", FieldName(field));
3633         printer->Indent();
3634         have_enclosing_if = true;
3635       } else {
3636         // Without field presence: field is serialized only if it has a
3637         // non-default value.
3638         have_enclosing_if = EmitFieldNonDefaultCondition(
3639             printer, "this->", field);
3640       }
3641 
3642       field_generators_.get(field).GenerateByteSize(printer);
3643 
3644       if (have_enclosing_if) {
3645         printer->Outdent();
3646         printer->Print(
3647           "}\n"
3648           "\n");
3649       }
3650     }
3651   }
3652 
3653   if (chunk_block_in_progress) {
3654     printer->Outdent();
3655     printer->Print("}\n");
3656   }
3657 
3658   // Repeated fields don't use _has_bits_ so we count them in a separate
3659   // pass.
3660   for (int i = 0; i < descriptor_->field_count(); i++) {
3661     const FieldDescriptor* field = descriptor_->field(i);
3662 
3663     if (field->is_repeated()) {
3664       PrintFieldComment(printer, field);
3665       field_generators_.get(field).GenerateByteSize(printer);
3666       printer->Print("\n");
3667     }
3668   }
3669 
3670   // Fields inside a oneof don't use _has_bits_ so we count them in a separate
3671   // pass.
3672   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
3673     printer->Print(
3674         "switch ($oneofname$_case()) {\n",
3675         "oneofname", descriptor_->oneof_decl(i)->name());
3676     printer->Indent();
3677     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
3678       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
3679       PrintFieldComment(printer, field);
3680       printer->Print(
3681           "case k$field_name$: {\n",
3682           "field_name", UnderscoresToCamelCase(field->name(), true));
3683       printer->Indent();
3684       field_generators_.get(field).GenerateByteSize(printer);
3685       printer->Print(
3686           "break;\n");
3687       printer->Outdent();
3688       printer->Print(
3689           "}\n");
3690     }
3691     printer->Print(
3692         "case $cap_oneof_name$_NOT_SET: {\n"
3693         "  break;\n"
3694         "}\n",
3695         "cap_oneof_name",
3696         ToUpper(descriptor_->oneof_decl(i)->name()));
3697     printer->Outdent();
3698     printer->Print(
3699         "}\n");
3700   }
3701 
3702   if (descriptor_->extension_range_count() > 0) {
3703     printer->Print(
3704       "total_size += _extensions_.ByteSize();\n"
3705       "\n");
3706   }
3707 
3708   if (PreserveUnknownFields(descriptor_)) {
3709     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3710       printer->Print(
3711         "if (_internal_metadata_.have_unknown_fields()) {\n"
3712         "  total_size +=\n"
3713         "    ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
3714         "      unknown_fields());\n"
3715         "}\n");
3716     } else {
3717       printer->Print(
3718         "total_size += unknown_fields().size();\n"
3719         "\n");
3720     }
3721   }
3722 
3723   // We update _cached_size_ even though this is a const method.  In theory,
3724   // this is not thread-compatible, because concurrent writes have undefined
3725   // results.  In practice, since any concurrent writes will be writing the
3726   // exact same value, it works on all common processors.  In a future version
3727   // of C++, _cached_size_ should be made into an atomic<int>.
3728   printer->Print(
3729     "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
3730     "_cached_size_ = total_size;\n"
3731     "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
3732     "return total_size;\n");
3733 
3734   printer->Outdent();
3735   printer->Print("}\n");
3736 }
3737 
3738 void MessageGenerator::
GenerateIsInitialized(io::Printer * printer)3739 GenerateIsInitialized(io::Printer* printer) {
3740   printer->Print(
3741     "bool $classname$::IsInitialized() const {\n",
3742     "classname", classname_);
3743   printer->Indent();
3744 
3745   if (HasFieldPresence(descriptor_->file())) {
3746     // Check that all required fields in this message are set.  We can do this
3747     // most efficiently by checking 32 "has bits" at a time.
3748     int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
3749     for (int i = 0; i < has_bits_array_size; i++) {
3750       uint32 mask = 0;
3751       for (int bit = 0; bit < 32; bit++) {
3752         int index = i * 32 + bit;
3753         if (index >= descriptor_->field_count()) break;
3754         const FieldDescriptor* field = descriptor_->field(index);
3755 
3756         if (field->is_required()) {
3757           mask |= 1 << bit;
3758         }
3759       }
3760 
3761       if (mask != 0) {
3762         printer->Print(
3763           "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
3764           "i", SimpleItoa(i),
3765           "mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));
3766       }
3767     }
3768   }
3769 
3770   // Now check that all embedded messages are initialized.
3771   printer->Print("\n");
3772   for (int i = 0; i < descriptor_->field_count(); i++) {
3773     const FieldDescriptor* field = descriptor_->field(i);
3774     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
3775         !ShouldIgnoreRequiredFieldCheck(field, options_) &&
3776         HasRequiredFields(field->message_type(), options_)) {
3777       if (field->is_repeated()) {
3778         printer->Print(
3779           "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
3780           " return false;\n",
3781           "name", FieldName(field));
3782       } else {
3783         if (field->options().weak() || !field->containing_oneof()) {
3784           // For weak fields, use the data member (::google::protobuf::Message*) instead
3785           // of the getter to avoid a link dependency on the weak message type
3786           // which is only forward declared.
3787           printer->Print(
3788               "if (has_$name$()) {\n"
3789               "  if (!this->$name$_->IsInitialized()) return false;\n"
3790               "}\n",
3791             "name", FieldName(field));
3792         } else {
3793           printer->Print(
3794             "if (has_$name$()) {\n"
3795             "  if (!this->$name$().IsInitialized()) return false;\n"
3796             "}\n",
3797             "name", FieldName(field));
3798         }
3799       }
3800     }
3801   }
3802 
3803   if (descriptor_->extension_range_count() > 0) {
3804     printer->Print(
3805       "\n"
3806       "if (!_extensions_.IsInitialized()) return false;");
3807   }
3808 
3809   printer->Outdent();
3810   printer->Print(
3811     "  return true;\n"
3812     "}\n");
3813 }
3814 
3815 
3816 }  // namespace cpp
3817 }  // namespace compiler
3818 }  // namespace protobuf
3819 }  // namespace google
3820