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::__anon921c5a8a0111::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::__anon921c5a8a0111::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["superclass"] = SuperClassName(descriptor_, options_);
842
843 printer->Print(vars,
844 "template <class T>\n"
845 "class $classname$ : public $superclass$ {\n"
846 " public:\n");
847 printer->Indent();
848
849 printer->Print(vars,
850 "$classname$() {}\n"
851 "virtual ~$classname$() {}\n"
852 "\n");
853
854 // Generate dependent accessor methods for all fields.
855 GenerateDependentFieldAccessorDeclarations(printer);
856
857 printer->Outdent();
858 printer->Print("};\n");
859 }
860
861 void MessageGenerator::
GenerateClassDefinition(io::Printer * printer)862 GenerateClassDefinition(io::Printer* printer) {
863 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
864 // map entry message doesn't need class definition. Since map entry message
865 // cannot be a top level class, we just need to avoid calling
866 // GenerateClassDefinition here.
867 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
868 nested_generators_[i]->GenerateClassDefinition(printer);
869 printer->Print("\n");
870 printer->Print(kThinSeparator);
871 printer->Print("\n");
872 }
873
874 if (use_dependent_base_) {
875 GenerateDependentBaseClassDefinition(printer);
876 printer->Print("\n");
877 }
878
879 map<string, string> vars;
880 vars["classname"] = classname_;
881 vars["field_count"] = SimpleItoa(descriptor_->field_count());
882 vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
883 if (options_.dllexport_decl.empty()) {
884 vars["dllexport"] = "";
885 } else {
886 vars["dllexport"] = options_.dllexport_decl + " ";
887 }
888 if (use_dependent_base_) {
889 vars["superclass"] =
890 DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
891 } else {
892 vars["superclass"] = SuperClassName(descriptor_, options_);
893 }
894 printer->Print(vars,
895 "class $dllexport$$classname$ : public $superclass$ {\n");
896 printer->Annotate("classname", descriptor_);
897 if (use_dependent_base_) {
898 printer->Print(vars, " friend class $superclass$;\n");
899 }
900 printer->Print(" public:\n");
901 printer->Indent();
902
903 printer->Print(vars,
904 "$classname$();\n"
905 "virtual ~$classname$();\n"
906 "\n"
907 "$classname$(const $classname$& from);\n"
908 "\n"
909 "inline $classname$& operator=(const $classname$& from) {\n"
910 " CopyFrom(from);\n"
911 " return *this;\n"
912 "}\n"
913 "\n");
914
915 if (PreserveUnknownFields(descriptor_)) {
916 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
917 printer->Print(
918 "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
919 " return _internal_metadata_.unknown_fields();\n"
920 "}\n"
921 "\n"
922 "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
923 " return _internal_metadata_.mutable_unknown_fields();\n"
924 "}\n"
925 "\n");
926 } else {
927 if (SupportsArenas(descriptor_)) {
928 printer->Print(
929 "inline const ::std::string& unknown_fields() const {\n"
930 " return _unknown_fields_.Get(\n"
931 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
932 "}\n"
933 "\n"
934 "inline ::std::string* mutable_unknown_fields() {\n"
935 " return _unknown_fields_.Mutable(\n"
936 " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
937 " GetArenaNoVirtual());\n"
938 "}\n"
939 "\n");
940 } else {
941 printer->Print(
942 "inline const ::std::string& unknown_fields() const {\n"
943 " return _unknown_fields_.GetNoArena(\n"
944 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
945 "}\n"
946 "\n"
947 "inline ::std::string* mutable_unknown_fields() {\n"
948 " return _unknown_fields_.MutableNoArena(\n"
949 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
950 "}\n"
951 "\n");
952 }
953 }
954 }
955
956 // N.B.: We exclude GetArena() when arena support is disabled, falling back on
957 // MessageLite's implementation which returns NULL rather than generating our
958 // own method which returns NULL, in order to reduce code size.
959 if (SupportsArenas(descriptor_)) {
960 // virtual method version of GetArenaNoVirtual(), required for generic dispatch given a
961 // MessageLite* (e.g., in RepeatedField::AddAllocated()).
962 printer->Print(
963 "inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }\n"
964 "inline void* GetMaybeArenaPointer() const {\n"
965 " return MaybeArenaPtr();\n"
966 "}\n");
967 }
968
969 // Only generate this member if it's not disabled.
970 if (HasDescriptorMethods(descriptor_->file(), options_) &&
971 !descriptor_->options().no_standard_descriptor_accessor()) {
972 printer->Print(vars,
973 "static const ::google::protobuf::Descriptor* descriptor();\n");
974 }
975
976 printer->Print(vars,
977 "static const $classname$& default_instance();\n"
978 "\n");
979
980 // Generate enum values for every field in oneofs. One list is generated for
981 // each oneof with an additional *_NOT_SET value.
982 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
983 printer->Print(
984 "enum $camel_oneof_name$Case {\n",
985 "camel_oneof_name",
986 UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
987 printer->Indent();
988 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
989 printer->Print(
990 "k$field_name$ = $field_number$,\n",
991 "field_name",
992 UnderscoresToCamelCase(
993 descriptor_->oneof_decl(i)->field(j)->name(), true),
994 "field_number",
995 SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
996 }
997 printer->Print(
998 "$cap_oneof_name$_NOT_SET = 0,\n",
999 "cap_oneof_name",
1000 ToUpper(descriptor_->oneof_decl(i)->name()));
1001 printer->Outdent();
1002 printer->Print(
1003 "};\n"
1004 "\n");
1005 }
1006
1007 if (!StaticInitializersForced(descriptor_->file(), options_)) {
1008 printer->Print(vars,
1009 "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
1010 "// Returns the internal default instance pointer. This function can\n"
1011 "// return NULL thus should not be used by the user. This is intended\n"
1012 "// for Protobuf internal code. Please use default_instance() declared\n"
1013 "// above instead.\n"
1014 "static inline const $classname$* internal_default_instance() {\n"
1015 " return default_instance_;\n"
1016 "}\n"
1017 "#endif\n"
1018 "\n");
1019 }
1020
1021
1022 if (SupportsArenas(descriptor_)) {
1023 printer->Print(vars,
1024 "void UnsafeArenaSwap($classname$* other);\n");
1025 }
1026
1027 if (IsAnyMessage(descriptor_)) {
1028 printer->Print(vars,
1029 "// implements Any -----------------------------------------------\n"
1030 "\n"
1031 "void PackFrom(const ::google::protobuf::Message& message);\n"
1032 "void PackFrom(const ::google::protobuf::Message& message,\n"
1033 " const ::std::string& type_url_prefix);\n"
1034 "bool UnpackTo(::google::protobuf::Message* message) const;\n"
1035 "template<typename T> bool Is() const {\n"
1036 " return _any_metadata_.Is<T>();\n"
1037 "}\n"
1038 "\n");
1039 }
1040
1041 printer->Print(vars,
1042 "void Swap($classname$* other);\n"
1043 "\n"
1044 "// implements Message ----------------------------------------------\n"
1045 "\n"
1046 "inline $classname$* New() const { return New(NULL); }\n"
1047 "\n"
1048 "$classname$* New(::google::protobuf::Arena* arena) const;\n");
1049
1050 if (HasGeneratedMethods(descriptor_->file(), options_)) {
1051 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1052 printer->Print(vars,
1053 "void CopyFrom(const ::google::protobuf::Message& from);\n"
1054 "void MergeFrom(const ::google::protobuf::Message& from);\n");
1055 } else {
1056 printer->Print(vars,
1057 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
1058 }
1059
1060 printer->Print(vars,
1061 "void CopyFrom(const $classname$& from);\n"
1062 "void MergeFrom(const $classname$& from);\n"
1063 "void Clear();\n"
1064 "bool IsInitialized() const;\n"
1065 "\n"
1066 "int ByteSize() const;\n"
1067 "bool MergePartialFromCodedStream(\n"
1068 " ::google::protobuf::io::CodedInputStream* input);\n"
1069 "void SerializeWithCachedSizes(\n"
1070 " ::google::protobuf::io::CodedOutputStream* output) const;\n");
1071 // DiscardUnknownFields() is implemented in message.cc using reflections. We
1072 // need to implement this function in generated code for messages.
1073 if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
1074 printer->Print(
1075 "void DiscardUnknownFields();\n");
1076 }
1077 if (HasFastArraySerialization(descriptor_->file(), options_)) {
1078 printer->Print(
1079 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
1080 }
1081 }
1082
1083 // Check all FieldDescriptors including those in oneofs to estimate
1084 // whether ::std::string is likely to be used, and depending on that
1085 // estimate, set uses_string_ to true or false. That contols
1086 // whether to force initialization of empty_string_ in SharedCtor().
1087 // It's often advantageous to do so to keep "is empty_string_
1088 // inited?" code from appearing all over the place.
1089 vector<const FieldDescriptor*> descriptors;
1090 for (int i = 0; i < descriptor_->field_count(); i++) {
1091 descriptors.push_back(descriptor_->field(i));
1092 }
1093 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1094 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1095 descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
1096 }
1097 }
1098 uses_string_ = false;
1099 if (PreserveUnknownFields(descriptor_) &&
1100 !UseUnknownFieldSet(descriptor_->file(), options_)) {
1101 uses_string_ = true;
1102 }
1103 for (int i = 0; i < descriptors.size(); i++) {
1104 const FieldDescriptor* field = descriptors[i];
1105 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
1106 switch (field->options().ctype()) {
1107 default: uses_string_ = true; break;
1108 }
1109 }
1110 }
1111
1112 printer->Print(
1113 "int GetCachedSize() const { return _cached_size_; }\n"
1114 "private:\n"
1115 "void SharedCtor();\n"
1116 "void SharedDtor();\n"
1117 "void SetCachedSize(int size) const;\n"
1118 "void InternalSwap($classname$* other);\n",
1119 "classname", classname_);
1120 if (SupportsArenas(descriptor_)) {
1121 printer->Print(
1122 "protected:\n"
1123 "explicit $classname$(::google::protobuf::Arena* arena);\n"
1124 "private:\n"
1125 "static void ArenaDtor(void* object);\n"
1126 "inline void RegisterArenaDtor(::google::protobuf::Arena* arena);\n",
1127 "classname", classname_);
1128 }
1129
1130 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1131 printer->Print(
1132 "private:\n"
1133 "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
1134 " return _internal_metadata_.arena();\n"
1135 "}\n"
1136 "inline void* MaybeArenaPtr() const {\n"
1137 " return _internal_metadata_.raw_arena_ptr();\n"
1138 "}\n"
1139 "public:\n"
1140 "\n");
1141 } else {
1142 printer->Print(
1143 "private:\n"
1144 "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
1145 " return _arena_ptr_;\n"
1146 "}\n"
1147 "inline ::google::protobuf::Arena* MaybeArenaPtr() const {\n"
1148 " return _arena_ptr_;\n"
1149 "}\n"
1150 "public:\n"
1151 "\n");
1152 }
1153
1154 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1155 printer->Print(
1156 "::google::protobuf::Metadata GetMetadata() const;\n"
1157 "\n");
1158 } else {
1159 printer->Print(
1160 "::std::string GetTypeName() const;\n"
1161 "\n");
1162 }
1163
1164 printer->Print(
1165 "// nested types ----------------------------------------------------\n"
1166 "\n");
1167
1168 // Import all nested message classes into this class's scope with typedefs.
1169 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1170 const Descriptor* nested_type = descriptor_->nested_type(i);
1171 if (!IsMapEntryMessage(nested_type)) {
1172 printer->Print("typedef $nested_full_name$ $nested_name$;\n",
1173 "nested_name", nested_type->name(),
1174 "nested_full_name", ClassName(nested_type, false));
1175 }
1176 }
1177
1178 if (descriptor_->nested_type_count() > 0) {
1179 printer->Print("\n");
1180 }
1181
1182 // Import all nested enums and their values into this class's scope with
1183 // typedefs and constants.
1184 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1185 enum_generators_[i]->GenerateSymbolImports(printer);
1186 printer->Print("\n");
1187 }
1188
1189 printer->Print(
1190 "// accessors -------------------------------------------------------\n"
1191 "\n");
1192
1193 // Generate accessor methods for all fields.
1194 GenerateFieldAccessorDeclarations(printer);
1195
1196 // Declare extension identifiers.
1197 for (int i = 0; i < descriptor_->extension_count(); i++) {
1198 extension_generators_[i]->GenerateDeclaration(printer);
1199 }
1200
1201
1202 printer->Print(
1203 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
1204 "full_name", descriptor_->full_name());
1205
1206 // Generate private members.
1207 printer->Outdent();
1208 printer->Print(" private:\n");
1209 printer->Indent();
1210
1211
1212 for (int i = 0; i < descriptor_->field_count(); i++) {
1213 if (!descriptor_->field(i)->is_repeated()) {
1214 // set_has_***() generated in all proto1/2 code and in oneofs (only) for
1215 // messages without true field presence.
1216 if (HasFieldPresence(descriptor_->file()) ||
1217 descriptor_->field(i)->containing_oneof()) {
1218 printer->Print(
1219 "inline void set_has_$name$();\n",
1220 "name", FieldName(descriptor_->field(i)));
1221 }
1222 // clear_has_***() generated only for non-oneof fields
1223 // in proto1/2.
1224 if (!descriptor_->field(i)->containing_oneof() &&
1225 HasFieldPresence(descriptor_->file())) {
1226 printer->Print(
1227 "inline void clear_has_$name$();\n",
1228 "name", FieldName(descriptor_->field(i)));
1229 }
1230 }
1231 }
1232 printer->Print("\n");
1233
1234 // Generate oneof function declarations
1235 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1236 printer->Print(
1237 "inline bool has_$oneof_name$() const;\n"
1238 "void clear_$oneof_name$();\n"
1239 "inline void clear_has_$oneof_name$();\n\n",
1240 "oneof_name", descriptor_->oneof_decl(i)->name());
1241 }
1242
1243 if (HasGeneratedMethods(descriptor_->file(), options_) &&
1244 !descriptor_->options().message_set_wire_format() &&
1245 num_required_fields_ > 1) {
1246 printer->Print(
1247 "// helper for ByteSize()\n"
1248 "int RequiredFieldsByteSizeFallback() const;\n\n");
1249 }
1250
1251 // Prepare decls for _cached_size_ and _has_bits_. Their position in the
1252 // output will be determined later.
1253
1254 bool need_to_emit_cached_size = true;
1255 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
1256 const string cached_size_decl = "mutable int _cached_size_;\n";
1257
1258 // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
1259 size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
1260 if (descriptor_->field_count() == 0) {
1261 // Zero-size arrays aren't technically allowed, and MSVC in particular
1262 // doesn't like them. We still need to declare these arrays to make
1263 // other code compile. Since this is an uncommon case, we'll just declare
1264 // them with size 1 and waste some space. Oh well.
1265 sizeof_has_bits = 4;
1266 }
1267 const string has_bits_decl = sizeof_has_bits == 0 ? "" :
1268 "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
1269
1270
1271 // To minimize padding, data members are divided into three sections:
1272 // (1) members assumed to align to 8 bytes
1273 // (2) members corresponding to message fields, re-ordered to optimize
1274 // alignment.
1275 // (3) members assumed to align to 4 bytes.
1276
1277 // Members assumed to align to 8 bytes:
1278
1279 if (descriptor_->extension_range_count() > 0) {
1280 printer->Print(
1281 "::google::protobuf::internal::ExtensionSet _extensions_;\n"
1282 "\n");
1283 }
1284
1285 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1286 printer->Print(
1287 "::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
1288 } else {
1289 printer->Print(
1290 "::google::protobuf::internal::ArenaStringPtr _unknown_fields_;\n"
1291 "::google::protobuf::Arena* _arena_ptr_;\n"
1292 "\n");
1293 }
1294
1295 if (SupportsArenas(descriptor_)) {
1296 printer->Print(
1297 "friend class ::google::protobuf::Arena;\n"
1298 "typedef void InternalArenaConstructable_;\n"
1299 "typedef void DestructorSkippable_;\n");
1300 }
1301
1302 if (HasFieldPresence(descriptor_->file())) {
1303 // _has_bits_ is frequently accessed, so to reduce code size and improve
1304 // speed, it should be close to the start of the object. But, try not to
1305 // waste space:_has_bits_ by itself always makes sense if its size is a
1306 // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
1307 // will work well.
1308 printer->Print(has_bits_decl.c_str());
1309 if ((sizeof_has_bits % 8) != 0) {
1310 printer->Print(cached_size_decl.c_str());
1311 need_to_emit_cached_size = false;
1312 }
1313 } else {
1314 // Without field presence, we need another way to disambiguate the default
1315 // instance, because the default instance's submessage fields (if any) store
1316 // pointers to the default instances of the submessages even when they
1317 // aren't present. Alternatives to this approach might be to (i) use a
1318 // tagged pointer on all message fields, setting a tag bit for "not really
1319 // present, just default instance"; or (ii) comparing |this| against the
1320 // return value from GeneratedMessageFactory::GetPrototype() in all
1321 // has_$field$() calls. However, both of these options are much more
1322 // expensive (in code size and CPU overhead) than just checking a field in
1323 // the message. Long-term, the best solution would be to rearchitect the
1324 // default instance design not to store pointers to submessage default
1325 // instances, and have reflection get those some other way; but that change
1326 // would have too much impact on proto2.
1327 printer->Print(
1328 "bool _is_default_instance_;\n");
1329 }
1330
1331 // Field members:
1332
1333 // List fields which doesn't belong to any oneof
1334 vector<const FieldDescriptor*> fields;
1335 hash_map<string, int> fieldname_to_chunk;
1336 for (int i = 0; i < descriptor_->field_count(); i++) {
1337 if (!descriptor_->field(i)->containing_oneof()) {
1338 const FieldDescriptor* field = descriptor_->field(i);
1339 fields.push_back(field);
1340 fieldname_to_chunk[FieldName(field)] = i / 8;
1341 }
1342 }
1343 OptimizePadding(&fields);
1344 // Emit some private and static members
1345 runs_of_fields_ = vector< vector<string> >(1);
1346 for (int i = 0; i < fields.size(); ++i) {
1347 const FieldDescriptor* field = fields[i];
1348 const FieldGenerator& generator = field_generators_.get(field);
1349 generator.GenerateStaticMembers(printer);
1350 generator.GeneratePrivateMembers(printer);
1351 if (CanClearByZeroing(field)) {
1352 const string& fieldname = FieldName(field);
1353 if (!runs_of_fields_.back().empty() &&
1354 (fieldname_to_chunk[runs_of_fields_.back().back()] !=
1355 fieldname_to_chunk[fieldname])) {
1356 runs_of_fields_.push_back(vector<string>());
1357 }
1358 runs_of_fields_.back().push_back(fieldname);
1359 } else if (!runs_of_fields_.back().empty()) {
1360 runs_of_fields_.push_back(vector<string>());
1361 }
1362 }
1363
1364 // For each oneof generate a union
1365 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1366 printer->Print(
1367 "union $camel_oneof_name$Union {\n"
1368 // explicit empty constructor is needed when union contains
1369 // ArenaStringPtr members for string fields.
1370 " $camel_oneof_name$Union() {}\n",
1371 "camel_oneof_name",
1372 UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
1373 printer->Indent();
1374 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1375 field_generators_.get(descriptor_->oneof_decl(i)->
1376 field(j)).GeneratePrivateMembers(printer);
1377 }
1378 printer->Outdent();
1379 printer->Print(
1380 "} $oneof_name$_;\n",
1381 "oneof_name", descriptor_->oneof_decl(i)->name());
1382 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1383 field_generators_.get(descriptor_->oneof_decl(i)->
1384 field(j)).GenerateStaticMembers(printer);
1385 }
1386 }
1387
1388 // Members assumed to align to 4 bytes:
1389
1390 if (need_to_emit_cached_size) {
1391 printer->Print(cached_size_decl.c_str());
1392 need_to_emit_cached_size = false;
1393 }
1394
1395 // Generate _oneof_case_.
1396 if (descriptor_->oneof_decl_count() > 0) {
1397 printer->Print(vars,
1398 "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
1399 "\n");
1400 }
1401
1402 // Generate _any_metadata_ for the Any type.
1403 if (IsAnyMessage(descriptor_)) {
1404 printer->Print(vars,
1405 "::google::protobuf::internal::AnyMetadata _any_metadata_;\n");
1406 }
1407
1408 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
1409 // friends so that they can access private static variables like
1410 // default_instance_ and reflection_.
1411 PrintHandlingOptionalStaticInitializers(
1412 descriptor_->file(), options_, printer,
1413 // With static initializers.
1414 "friend void $dllexport_decl$ $adddescriptorsname$();\n",
1415 // Without.
1416 "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
1417 // Vars.
1418 "dllexport_decl", options_.dllexport_decl, "adddescriptorsname",
1419 GlobalAddDescriptorsName(descriptor_->file()->name()));
1420
1421 printer->Print(
1422 "friend void $assigndescriptorsname$();\n"
1423 "friend void $shutdownfilename$();\n"
1424 "\n",
1425 "assigndescriptorsname",
1426 GlobalAssignDescriptorsName(descriptor_->file()->name()),
1427 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
1428
1429 printer->Print(
1430 "void InitAsDefaultInstance();\n"
1431 "static $classname$* default_instance_;\n",
1432 "classname", classname_);
1433
1434 printer->Outdent();
1435 printer->Print(vars, "};");
1436 GOOGLE_DCHECK(!need_to_emit_cached_size);
1437 }
1438
1439 void MessageGenerator::
GenerateDependentInlineMethods(io::Printer * printer)1440 GenerateDependentInlineMethods(io::Printer* printer) {
1441 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1442 // map entry message doesn't need inline methods. Since map entry message
1443 // cannot be a top level class, we just need to avoid calling
1444 // GenerateInlineMethods here.
1445 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1446 nested_generators_[i]->GenerateDependentInlineMethods(printer);
1447 printer->Print(kThinSeparator);
1448 printer->Print("\n");
1449 }
1450
1451 GenerateDependentFieldAccessorDefinitions(printer);
1452 }
1453
1454 void MessageGenerator::
GenerateInlineMethods(io::Printer * printer,bool is_inline)1455 GenerateInlineMethods(io::Printer* printer, bool is_inline) {
1456 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1457 // map entry message doesn't need inline methods. Since map entry message
1458 // cannot be a top level class, we just need to avoid calling
1459 // GenerateInlineMethods here.
1460 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1461 nested_generators_[i]->GenerateInlineMethods(printer, is_inline);
1462 printer->Print(kThinSeparator);
1463 printer->Print("\n");
1464 }
1465
1466 GenerateFieldAccessorDefinitions(printer, is_inline);
1467
1468 // Generate oneof_case() functions.
1469 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1470 map<string, string> vars;
1471 vars["class_name"] = classname_;
1472 vars["camel_oneof_name"] = UnderscoresToCamelCase(
1473 descriptor_->oneof_decl(i)->name(), true);
1474 vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
1475 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
1476 vars["inline"] = is_inline ? "inline " : "";
1477 printer->Print(
1478 vars,
1479 "$inline$"
1480 "$class_name$::$camel_oneof_name$Case $class_name$::"
1481 "$oneof_name$_case() const {\n"
1482 " return $class_name$::$camel_oneof_name$Case("
1483 "_oneof_case_[$oneof_index$]);\n"
1484 "}\n");
1485 }
1486 }
1487
1488 void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer * printer)1489 GenerateDescriptorDeclarations(io::Printer* printer) {
1490 if (!IsMapEntryMessage(descriptor_)) {
1491 printer->Print(
1492 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
1493 "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
1494 " $name$_reflection_ = NULL;\n",
1495 "name", classname_);
1496 } else {
1497 printer->Print(
1498 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
1499 "name", classname_);
1500 }
1501
1502 // Generate oneof default instance for reflection usage.
1503 if (descriptor_->oneof_decl_count() > 0) {
1504 printer->Print("struct $name$OneofInstance {\n",
1505 "name", classname_);
1506 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1507 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1508 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1509 printer->Print(" ");
1510 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1511 (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
1512 EffectiveStringCType(field) != FieldOptions::STRING)) {
1513 printer->Print("const ");
1514 }
1515 field_generators_.get(field).GeneratePrivateMembers(printer);
1516 }
1517 }
1518
1519 printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
1520 "name", classname_);
1521 }
1522
1523 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1524 nested_generators_[i]->GenerateDescriptorDeclarations(printer);
1525 }
1526
1527 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1528 printer->Print(
1529 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
1530 "name", ClassName(descriptor_->enum_type(i), false));
1531 }
1532 }
1533
1534 void MessageGenerator::
GenerateDescriptorInitializer(io::Printer * printer,int index)1535 GenerateDescriptorInitializer(io::Printer* printer, int index) {
1536 // TODO(kenton): Passing the index to this method is redundant; just use
1537 // descriptor_->index() instead.
1538 map<string, string> vars;
1539 vars["classname"] = classname_;
1540 vars["index"] = SimpleItoa(index);
1541
1542 // Obtain the descriptor from the parent's descriptor.
1543 if (descriptor_->containing_type() == NULL) {
1544 printer->Print(vars,
1545 "$classname$_descriptor_ = file->message_type($index$);\n");
1546 } else {
1547 vars["parent"] = ClassName(descriptor_->containing_type(), false);
1548 printer->Print(vars,
1549 "$classname$_descriptor_ = "
1550 "$parent$_descriptor_->nested_type($index$);\n");
1551 }
1552
1553 if (IsMapEntryMessage(descriptor_)) return;
1554
1555 // Generate the offsets.
1556 GenerateOffsets(printer);
1557
1558 const bool pass_pool_and_factory = false;
1559 vars["fn"] = pass_pool_and_factory ?
1560 "new ::google::protobuf::internal::GeneratedMessageReflection" :
1561 "::google::protobuf::internal::GeneratedMessageReflection"
1562 "::NewGeneratedMessageReflection";
1563 // Construct the reflection object.
1564 printer->Print(vars,
1565 "$classname$_reflection_ =\n"
1566 " $fn$(\n"
1567 " $classname$_descriptor_,\n"
1568 " $classname$::default_instance_,\n"
1569 " $classname$_offsets_,\n");
1570 if (!HasFieldPresence(descriptor_->file())) {
1571 // If we don't have field presence, then _has_bits_ does not exist.
1572 printer->Print(vars,
1573 " -1,\n");
1574 } else {
1575 printer->Print(vars,
1576 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n");
1577 }
1578
1579 // Unknown field offset: either points to the unknown field set if embedded
1580 // directly, or indicates that the unknown field set is stored as part of the
1581 // internal metadata if not.
1582 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1583 printer->Print(vars,
1584 " -1,\n");
1585 } else {
1586 printer->Print(vars,
1587 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1588 "$classname$, _unknown_fields_),\n");
1589 }
1590
1591 if (descriptor_->extension_range_count() > 0) {
1592 printer->Print(vars,
1593 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1594 "$classname$, _extensions_),\n");
1595 } else {
1596 // No extensions.
1597 printer->Print(vars,
1598 " -1,\n");
1599 }
1600
1601 if (descriptor_->oneof_decl_count() > 0) {
1602 printer->Print(vars,
1603 " $classname$_default_oneof_instance_,\n"
1604 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1605 "$classname$, _oneof_case_[0]),\n");
1606 }
1607
1608 if (pass_pool_and_factory) {
1609 printer->Print(
1610 " ::google::protobuf::DescriptorPool::generated_pool(),\n");
1611 printer->Print(vars,
1612 " ::google::protobuf::MessageFactory::generated_factory(),\n");
1613 }
1614
1615 printer->Print(vars,
1616 " sizeof($classname$),\n");
1617
1618 // Arena offset: either an offset to the metadata struct that contains the
1619 // arena pointer and unknown field set (in a space-efficient way) if we use
1620 // that implementation strategy, or an offset directly to the arena pointer if
1621 // not (because e.g. we don't have an unknown field set).
1622 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1623 printer->Print(vars,
1624 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1625 "$classname$, _internal_metadata_),\n");
1626 } else {
1627 printer->Print(vars,
1628 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1629 "$classname$, _arena_),\n");
1630 }
1631
1632 // is_default_instance_ offset.
1633 if (HasFieldPresence(descriptor_->file())) {
1634 printer->Print(vars,
1635 " -1);\n");
1636 } else {
1637 printer->Print(vars,
1638 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1639 "$classname$, _is_default_instance_));\n");
1640 }
1641
1642 // Handle nested types.
1643 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1644 nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
1645 }
1646
1647 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1648 enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
1649 }
1650 }
1651
1652 void MessageGenerator::
GenerateTypeRegistrations(io::Printer * printer)1653 GenerateTypeRegistrations(io::Printer* printer) {
1654 // Register this message type with the message factory.
1655 if (!IsMapEntryMessage(descriptor_)) {
1656 printer->Print(
1657 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1658 " $classname$_descriptor_, &$classname$::default_instance());\n",
1659 "classname", classname_);
1660 }
1661 else {
1662 map<string, string> vars;
1663 CollectMapInfo(descriptor_, &vars);
1664 vars["classname"] = classname_;
1665
1666 const FieldDescriptor* val = descriptor_->FindFieldByName("value");
1667 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
1668 val->type() == FieldDescriptor::TYPE_ENUM) {
1669 const EnumValueDescriptor* default_value = val->default_value_enum();
1670 vars["default_enum_value"] = Int32ToString(default_value->number());
1671 } else {
1672 vars["default_enum_value"] = "0";
1673 }
1674
1675 printer->Print(vars,
1676 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1677 " $classname$_descriptor_,\n"
1678 " ::google::protobuf::internal::MapEntry<\n"
1679 " $key$,\n"
1680 " $val$,\n"
1681 " $key_wire_type$,\n"
1682 " $val_wire_type$,\n"
1683 " $default_enum_value$>::CreateDefaultInstance(\n"
1684 " $classname$_descriptor_));\n");
1685 }
1686
1687 // Handle nested types.
1688 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1689 nested_generators_[i]->GenerateTypeRegistrations(printer);
1690 }
1691 }
1692
1693 void MessageGenerator::
GenerateDefaultInstanceAllocator(io::Printer * printer)1694 GenerateDefaultInstanceAllocator(io::Printer* printer) {
1695 // Construct the default instances of all fields, as they will be used
1696 // when creating the default instance of the entire message.
1697 for (int i = 0; i < descriptor_->field_count(); i++) {
1698 field_generators_.get(descriptor_->field(i))
1699 .GenerateDefaultInstanceAllocator(printer);
1700 }
1701
1702 if (IsMapEntryMessage(descriptor_)) return;
1703
1704 // Construct the default instance. We can't call InitAsDefaultInstance() yet
1705 // because we need to make sure all default instances that this one might
1706 // depend on are constructed first.
1707 printer->Print(
1708 "$classname$::default_instance_ = new $classname$();\n",
1709 "classname", classname_);
1710
1711 if ((descriptor_->oneof_decl_count() > 0) &&
1712 HasDescriptorMethods(descriptor_->file(), options_)) {
1713 printer->Print(
1714 "$classname$_default_oneof_instance_ = new $classname$OneofInstance();\n",
1715 "classname", classname_);
1716 }
1717
1718 // Handle nested types.
1719 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1720 nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
1721 }
1722
1723 }
1724
1725 void MessageGenerator::
GenerateDefaultInstanceInitializer(io::Printer * printer)1726 GenerateDefaultInstanceInitializer(io::Printer* printer) {
1727 printer->Print(
1728 "$classname$::default_instance_->InitAsDefaultInstance();\n",
1729 "classname", classname_);
1730
1731 // Register extensions.
1732 for (int i = 0; i < descriptor_->extension_count(); i++) {
1733 extension_generators_[i]->GenerateRegistration(printer);
1734 }
1735
1736 // Handle nested types.
1737 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1738 // map entry message doesn't need to initialize default instance manually.
1739 // Since map entry message cannot be a top level class, we just need to
1740 // avoid calling DefaultInstanceInitializer here.
1741 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1742 nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
1743 }
1744 }
1745
1746 void MessageGenerator::
GenerateShutdownCode(io::Printer * printer)1747 GenerateShutdownCode(io::Printer* printer) {
1748 printer->Print(
1749 "delete $classname$::default_instance_;\n",
1750 "classname", classname_);
1751
1752 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1753 if (descriptor_->oneof_decl_count() > 0) {
1754 printer->Print(
1755 "delete $classname$_default_oneof_instance_;\n",
1756 "classname", classname_);
1757 }
1758 printer->Print(
1759 "delete $classname$_reflection_;\n",
1760 "classname", classname_);
1761 }
1762
1763 // Handle default instances of fields.
1764 for (int i = 0; i < descriptor_->field_count(); i++) {
1765 field_generators_.get(descriptor_->field(i))
1766 .GenerateShutdownCode(printer);
1767 }
1768
1769 // Handle nested types.
1770 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1771 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1772 nested_generators_[i]->GenerateShutdownCode(printer);
1773 }
1774 }
1775
1776 void MessageGenerator::
GenerateClassMethods(io::Printer * printer)1777 GenerateClassMethods(io::Printer* printer) {
1778 // mutable_unknown_fields wrapper function for LazyStringOutputStream
1779 // callback.
1780 if (PreserveUnknownFields(descriptor_) &&
1781 !UseUnknownFieldSet(descriptor_->file(), options_)) {
1782 printer->Print(
1783 "static ::std::string* MutableUnknownFieldsFor$classname$(\n"
1784 " $classname$* ptr) {\n"
1785 " return ptr->mutable_unknown_fields();\n"
1786 "}\n"
1787 "\n",
1788 "classname", classname_);
1789 }
1790 if (IsAnyMessage(descriptor_)) {
1791 printer->Print(
1792 "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n"
1793 " _any_metadata_.PackFrom(message);\n"
1794 "}\n"
1795 "\n"
1796 "void $classname$::PackFrom(const ::google::protobuf::Message& message,\n"
1797 " const ::std::string& type_url_prefix) {\n"
1798 " _any_metadata_.PackFrom(message, type_url_prefix);\n"
1799 "}\n"
1800 "\n"
1801 "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n"
1802 " return _any_metadata_.UnpackTo(message);\n"
1803 "}\n"
1804 "\n",
1805 "classname", classname_);
1806 }
1807
1808 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1809 enum_generators_[i]->GenerateMethods(printer);
1810 }
1811
1812 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1813 // map entry message doesn't need class methods. Since map entry message
1814 // cannot be a top level class, we just need to avoid calling
1815 // GenerateClassMethods here.
1816 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1817 nested_generators_[i]->GenerateClassMethods(printer);
1818 printer->Print("\n");
1819 printer->Print(kThinSeparator);
1820 printer->Print("\n");
1821 }
1822
1823 // Generate non-inline field definitions.
1824 for (int i = 0; i < descriptor_->field_count(); i++) {
1825 field_generators_.get(descriptor_->field(i))
1826 .GenerateNonInlineAccessorDefinitions(printer);
1827 }
1828
1829 // Generate field number constants.
1830 printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
1831 for (int i = 0; i < descriptor_->field_count(); i++) {
1832 const FieldDescriptor *field = descriptor_->field(i);
1833 printer->Print(
1834 "const int $classname$::$constant_name$;\n",
1835 "classname", ClassName(FieldScope(field), false),
1836 "constant_name", FieldConstantName(field));
1837 }
1838 printer->Print(
1839 "#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
1840 "\n");
1841
1842 // Define extension identifiers.
1843 for (int i = 0; i < descriptor_->extension_count(); i++) {
1844 extension_generators_[i]->GenerateDefinition(printer);
1845 }
1846
1847 GenerateStructors(printer);
1848 printer->Print("\n");
1849
1850 if (descriptor_->oneof_decl_count() > 0) {
1851 GenerateOneofClear(printer);
1852 printer->Print("\n");
1853 }
1854
1855 if (HasGeneratedMethods(descriptor_->file(), options_)) {
1856 GenerateClear(printer);
1857 printer->Print("\n");
1858
1859 GenerateMergeFromCodedStream(printer);
1860 printer->Print("\n");
1861
1862 GenerateSerializeWithCachedSizes(printer);
1863 printer->Print("\n");
1864
1865 if (HasFastArraySerialization(descriptor_->file(), options_)) {
1866 GenerateSerializeWithCachedSizesToArray(printer);
1867 printer->Print("\n");
1868 }
1869
1870 GenerateByteSize(printer);
1871 printer->Print("\n");
1872
1873 GenerateMergeFrom(printer);
1874 printer->Print("\n");
1875
1876 GenerateCopyFrom(printer);
1877 printer->Print("\n");
1878
1879 GenerateIsInitialized(printer);
1880 printer->Print("\n");
1881 }
1882
1883 GenerateSwap(printer);
1884 printer->Print("\n");
1885
1886 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1887 printer->Print(
1888 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
1889 " protobuf_AssignDescriptorsOnce();\n"
1890 " ::google::protobuf::Metadata metadata;\n"
1891 " metadata.descriptor = $classname$_descriptor_;\n"
1892 " metadata.reflection = $classname$_reflection_;\n"
1893 " return metadata;\n"
1894 "}\n"
1895 "\n",
1896 "classname", classname_);
1897 } else {
1898 printer->Print(
1899 "::std::string $classname$::GetTypeName() const {\n"
1900 " return \"$type_name$\";\n"
1901 "}\n"
1902 "\n",
1903 "classname", classname_,
1904 "type_name", descriptor_->full_name());
1905 }
1906
1907 }
1908
1909 void MessageGenerator::
GenerateOffsets(io::Printer * printer)1910 GenerateOffsets(io::Printer* printer) {
1911 printer->Print("static const int $classname$_offsets_[$field_count$] = {\n",
1912 "classname", classname_, "field_count",
1913 SimpleItoa(std::max(1, descriptor_->field_count() +
1914 descriptor_->oneof_decl_count())));
1915 printer->Indent();
1916
1917 for (int i = 0; i < descriptor_->field_count(); i++) {
1918 const FieldDescriptor* field = descriptor_->field(i);
1919 if (field->containing_oneof()) {
1920 printer->Print(
1921 "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
1922 "$classname$_default_oneof_instance_, $name$_),\n",
1923 "classname", classname_,
1924 "name", FieldName(field));
1925 } else {
1926 printer->Print(
1927 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
1928 "$name$_),\n",
1929 "classname", classname_,
1930 "name", FieldName(field));
1931 }
1932 }
1933
1934 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1935 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1936 printer->Print(
1937 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
1938 "classname", classname_,
1939 "name", oneof->name());
1940 }
1941
1942 printer->Outdent();
1943 printer->Print("};\n");
1944 }
1945
1946 void MessageGenerator::
GenerateSharedConstructorCode(io::Printer * printer)1947 GenerateSharedConstructorCode(io::Printer* printer) {
1948 printer->Print(
1949 "void $classname$::SharedCtor() {\n",
1950 "classname", classname_);
1951 printer->Indent();
1952
1953 if (!HasFieldPresence(descriptor_->file())) {
1954 printer->Print(
1955 " _is_default_instance_ = false;\n");
1956 }
1957
1958 printer->Print(StrCat(
1959 uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
1960 "_cached_size_ = 0;\n").c_str());
1961
1962 if (PreserveUnknownFields(descriptor_) &&
1963 !UseUnknownFieldSet(descriptor_->file(), options_)) {
1964 printer->Print(
1965 "_unknown_fields_.UnsafeSetDefault(\n"
1966 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
1967 }
1968
1969 for (int i = 0; i < descriptor_->field_count(); i++) {
1970 if (!descriptor_->field(i)->containing_oneof()) {
1971 field_generators_.get(descriptor_->field(i))
1972 .GenerateConstructorCode(printer);
1973 }
1974 }
1975
1976 if (HasFieldPresence(descriptor_->file())) {
1977 printer->Print(
1978 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1979 }
1980
1981 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1982 printer->Print(
1983 "clear_has_$oneof_name$();\n",
1984 "oneof_name", descriptor_->oneof_decl(i)->name());
1985 }
1986
1987 printer->Outdent();
1988 printer->Print("}\n\n");
1989 }
1990
1991 void MessageGenerator::
GenerateSharedDestructorCode(io::Printer * printer)1992 GenerateSharedDestructorCode(io::Printer* printer) {
1993 printer->Print(
1994 "void $classname$::SharedDtor() {\n",
1995 "classname", classname_);
1996 printer->Indent();
1997 if (SupportsArenas(descriptor_)) {
1998 // Do nothing when the message is allocated in an arena.
1999 printer->Print(
2000 "if (GetArenaNoVirtual() != NULL) {\n"
2001 " return;\n"
2002 "}\n"
2003 "\n");
2004 }
2005
2006 // Write the desctructor for _unknown_fields_ in lite runtime.
2007 if (PreserveUnknownFields(descriptor_) &&
2008 !UseUnknownFieldSet(descriptor_->file(), options_)) {
2009 if (SupportsArenas(descriptor_)) {
2010 printer->Print(
2011 "_unknown_fields_.Destroy(\n"
2012 " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
2013 " GetArenaNoVirtual());\n");
2014 } else {
2015 printer->Print(
2016 "_unknown_fields_.DestroyNoArena(\n"
2017 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
2018 }
2019 }
2020
2021 // Write the destructors for each field except oneof members.
2022 for (int i = 0; i < descriptor_->field_count(); i++) {
2023 if (!descriptor_->field(i)->containing_oneof()) {
2024 field_generators_.get(descriptor_->field(i))
2025 .GenerateDestructorCode(printer);
2026 }
2027 }
2028
2029 // Generate code to destruct oneofs. Clearing should do the work.
2030 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2031 printer->Print(
2032 "if (has_$oneof_name$()) {\n"
2033 " clear_$oneof_name$();\n"
2034 "}\n",
2035 "oneof_name", descriptor_->oneof_decl(i)->name());
2036 }
2037
2038 PrintHandlingOptionalStaticInitializers(
2039 descriptor_->file(), options_, printer,
2040 // With static initializers.
2041 "if (this != default_instance_) {\n",
2042 // Without.
2043 "if (this != &default_instance()) {\n");
2044
2045 // We need to delete all embedded messages.
2046 // TODO(kenton): If we make unset messages point at default instances
2047 // instead of NULL, then it would make sense to move this code into
2048 // MessageFieldGenerator::GenerateDestructorCode().
2049 for (int i = 0; i < descriptor_->field_count(); i++) {
2050 const FieldDescriptor* field = descriptor_->field(i);
2051
2052 if (!field->is_repeated() &&
2053 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2054 // Skip oneof members
2055 if (!field->containing_oneof()) {
2056 printer->Print(
2057 " delete $name$_;\n",
2058 "name", FieldName(field));
2059 }
2060 }
2061 }
2062
2063 printer->Outdent();
2064 printer->Print(
2065 " }\n"
2066 "}\n"
2067 "\n");
2068 }
2069
2070 void MessageGenerator::
GenerateArenaDestructorCode(io::Printer * printer)2071 GenerateArenaDestructorCode(io::Printer* printer) {
2072 // Generate the ArenaDtor() method. Track whether any fields actually produced
2073 // code that needs to be called.
2074 printer->Print(
2075 "void $classname$::ArenaDtor(void* object) {\n",
2076 "classname", classname_);
2077 printer->Indent();
2078
2079 // This code is placed inside a static method, rather than an ordinary one,
2080 // since that simplifies Arena's destructor list (ordinary function pointers
2081 // rather than member function pointers). _this is the object being
2082 // destructed.
2083 printer->Print(
2084 "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
2085 // avoid an "unused variable" warning in case no fields have dtor code.
2086 "(void)_this;\n",
2087 "classname", classname_);
2088
2089 bool need_registration = false;
2090 for (int i = 0; i < descriptor_->field_count(); i++) {
2091 if (field_generators_.get(descriptor_->field(i))
2092 .GenerateArenaDestructorCode(printer)) {
2093 need_registration = true;
2094 }
2095 }
2096 printer->Outdent();
2097 printer->Print(
2098 "}\n");
2099
2100 if (need_registration) {
2101 printer->Print(
2102 "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
2103 " if (arena != NULL) {\n"
2104 " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
2105 " }\n"
2106 "}\n",
2107 "classname", classname_);
2108 } else {
2109 printer->Print(
2110 "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
2111 "}\n",
2112 "classname", classname_);
2113 }
2114 }
2115
2116 void MessageGenerator::
GenerateStructors(io::Printer * printer)2117 GenerateStructors(io::Printer* printer) {
2118 string superclass;
2119 if (use_dependent_base_) {
2120 superclass =
2121 DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
2122 } else {
2123 superclass = SuperClassName(descriptor_, options_);
2124 }
2125 string initializer_with_arena = superclass + "()";
2126
2127 if (descriptor_->extension_range_count() > 0) {
2128 initializer_with_arena += ",\n _extensions_(arena)";
2129 }
2130
2131 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2132 initializer_with_arena += ",\n _internal_metadata_(arena)";
2133 } else {
2134 initializer_with_arena += ",\n _arena_ptr_(arena)";
2135 }
2136
2137 // Initialize member variables with arena constructor.
2138 for (int i = 0; i < descriptor_->field_count(); i++) {
2139 bool has_arena_constructor = descriptor_->field(i)->is_repeated();
2140 if (has_arena_constructor) {
2141 initializer_with_arena += string(",\n ") +
2142 FieldName(descriptor_->field(i)) + string("_(arena)");
2143 }
2144 }
2145
2146 if (IsAnyMessage(descriptor_)) {
2147 initializer_with_arena += ",\n _any_metadata_(&type_url, &value_)";
2148 }
2149
2150 string initializer_null;
2151 initializer_null = (UseUnknownFieldSet(descriptor_->file(), options_) ?
2152 ", _internal_metadata_(NULL)" : ", _arena_ptr_(NULL)");
2153 if (IsAnyMessage(descriptor_)) {
2154 initializer_null += ", _any_metadata_(&type_url_, &value_)";
2155 }
2156
2157 printer->Print(
2158 "$classname$::$classname$()\n"
2159 " : $superclass$()$initializer$ {\n"
2160 " SharedCtor();\n"
2161 " // @@protoc_insertion_point(constructor:$full_name$)\n"
2162 "}\n",
2163 "classname", classname_,
2164 "superclass", superclass,
2165 "full_name", descriptor_->full_name(),
2166 "initializer", initializer_null);
2167
2168 if (SupportsArenas(descriptor_)) {
2169 printer->Print(
2170 "\n"
2171 "$classname$::$classname$(::google::protobuf::Arena* arena)\n"
2172 " : $initializer$ {\n"
2173 " SharedCtor();\n"
2174 " RegisterArenaDtor(arena);\n"
2175 " // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
2176 "}\n",
2177 "initializer", initializer_with_arena,
2178 "classname", classname_,
2179 "superclass", superclass,
2180 "full_name", descriptor_->full_name());
2181 }
2182
2183 printer->Print(
2184 "\n"
2185 "void $classname$::InitAsDefaultInstance() {\n",
2186 "classname", classname_);
2187
2188 if (!HasFieldPresence(descriptor_->file())) {
2189 printer->Print(
2190 " _is_default_instance_ = true;\n");
2191 }
2192
2193 // The default instance needs all of its embedded message pointers
2194 // cross-linked to other default instances. We can't do this initialization
2195 // in the constructor because some other default instances may not have been
2196 // constructed yet at that time.
2197 // TODO(kenton): Maybe all message fields (even for non-default messages)
2198 // should be initialized to point at default instances rather than NULL?
2199 for (int i = 0; i < descriptor_->field_count(); i++) {
2200 const FieldDescriptor* field = descriptor_->field(i);
2201
2202 if (!field->is_repeated() &&
2203 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
2204 (field->containing_oneof() == NULL ||
2205 HasDescriptorMethods(descriptor_->file(), options_))) {
2206 string name;
2207 if (field->containing_oneof()) {
2208 name = classname_ + "_default_oneof_instance_->";
2209 }
2210 name += FieldName(field);
2211 PrintHandlingOptionalStaticInitializers(
2212 descriptor_->file(), options_, printer,
2213 // With static initializers.
2214 " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
2215 // Without.
2216 " $name$_ = const_cast< $type$*>(\n"
2217 " $type$::internal_default_instance());\n",
2218 // Vars.
2219 "name", name, "type", FieldMessageTypeName(field));
2220 } else if (field->containing_oneof() &&
2221 HasDescriptorMethods(descriptor_->file(), options_)) {
2222 field_generators_.get(descriptor_->field(i))
2223 .GenerateConstructorCode(printer);
2224 }
2225 }
2226 printer->Print(
2227 "}\n"
2228 "\n");
2229
2230 // Generate the copy constructor.
2231 printer->Print(
2232 "$classname$::$classname$(const $classname$& from)\n"
2233 " : $superclass$()",
2234 "classname", classname_,
2235 "superclass", superclass,
2236 "full_name", descriptor_->full_name());
2237 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2238 printer->Print(
2239 ",\n _internal_metadata_(NULL)");
2240 } else if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
2241 printer->Print(",\n _arena_ptr_(NULL)");
2242 }
2243 if (IsAnyMessage(descriptor_)) {
2244 printer->Print(",\n _any_metadata_(&type_url_, &value_)");
2245 }
2246 printer->Print(" {\n");
2247 printer->Print(
2248 " SharedCtor();\n"
2249 " MergeFrom(from);\n"
2250 " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
2251 "}\n"
2252 "\n",
2253 "classname", classname_,
2254 "superclass", superclass,
2255 "full_name", descriptor_->full_name());
2256
2257 // Generate the shared constructor code.
2258 GenerateSharedConstructorCode(printer);
2259
2260 // Generate the destructor.
2261 printer->Print(
2262 "$classname$::~$classname$() {\n"
2263 " // @@protoc_insertion_point(destructor:$full_name$)\n"
2264 " SharedDtor();\n"
2265 "}\n"
2266 "\n",
2267 "classname", classname_,
2268 "full_name", descriptor_->full_name());
2269
2270 // Generate the shared destructor code.
2271 GenerateSharedDestructorCode(printer);
2272
2273 // Generate the arena-specific destructor code.
2274 if (SupportsArenas(descriptor_)) {
2275 GenerateArenaDestructorCode(printer);
2276 }
2277
2278 // Generate SetCachedSize.
2279 printer->Print(
2280 "void $classname$::SetCachedSize(int size) const {\n"
2281 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
2282 " _cached_size_ = size;\n"
2283 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
2284 "}\n",
2285 "classname", classname_);
2286
2287 // Only generate this member if it's not disabled.
2288 if (HasDescriptorMethods(descriptor_->file(), options_) &&
2289 !descriptor_->options().no_standard_descriptor_accessor()) {
2290 printer->Print(
2291 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
2292 " protobuf_AssignDescriptorsOnce();\n"
2293 " return $classname$_descriptor_;\n"
2294 "}\n"
2295 "\n",
2296 "classname", classname_,
2297 "adddescriptorsname",
2298 GlobalAddDescriptorsName(descriptor_->file()->name()));
2299 }
2300
2301 printer->Print(
2302 "const $classname$& $classname$::default_instance() {\n",
2303 "classname", classname_);
2304
2305 PrintHandlingOptionalStaticInitializers(
2306 descriptor_->file(), options_, printer,
2307 // With static initializers.
2308 " if (default_instance_ == NULL) $adddescriptorsname$();\n",
2309 // Without.
2310 " $adddescriptorsname$();\n",
2311 // Vars.
2312 "adddescriptorsname",
2313 GlobalAddDescriptorsName(descriptor_->file()->name()));
2314
2315 printer->Print(
2316 " return *default_instance_;\n"
2317 "}\n"
2318 "\n"
2319 "$classname$* $classname$::default_instance_ = NULL;\n"
2320 "\n",
2321 "classname", classname_);
2322
2323 if (SupportsArenas(descriptor_)) {
2324 printer->Print(
2325 "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n"
2326 " return ::google::protobuf::Arena::CreateMessage<$classname$>(arena);\n"
2327 "}\n",
2328 "classname", classname_);
2329 } else {
2330 printer->Print(
2331 "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n"
2332 " $classname$* n = new $classname$;\n"
2333 " if (arena != NULL) {\n"
2334 " arena->Own(n);\n"
2335 " }\n"
2336 " return n;\n"
2337 "}\n",
2338 "classname", classname_);
2339 }
2340
2341 }
2342
2343 // Return the number of bits set in n, a non-negative integer.
popcnt(uint32 n)2344 static int popcnt(uint32 n) {
2345 int result = 0;
2346 while (n != 0) {
2347 result += (n & 1);
2348 n = n / 2;
2349 }
2350 return result;
2351 }
2352
2353 void MessageGenerator::
GenerateClear(io::Printer * printer)2354 GenerateClear(io::Printer* printer) {
2355 printer->Print(
2356 "void $classname$::Clear() {\n"
2357 "// @@protoc_insertion_point(message_clear_start:$full_name$)\n",
2358 "classname", classname_, "full_name", descriptor_->full_name());
2359 printer->Indent();
2360
2361 // Step 1: Extensions
2362 if (descriptor_->extension_range_count() > 0) {
2363 printer->Print("_extensions_.Clear();\n");
2364 }
2365
2366 // Step 2: Everything but extensions, repeateds, unions.
2367 // These are handled in chunks of 8. The first chunk is
2368 // the non-extensions-non-repeateds-non-unions in
2369 // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
2370 // and the second chunk is the same for
2371 // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
2372 // etc.
2373 set<int> step2_indices;
2374 hash_map<string, int> fieldname_to_chunk;
2375 hash_map<int, string> memsets_for_chunk;
2376 hash_map<int, int> memset_field_count_for_chunk;
2377 hash_set<string> handled; // fields that appear anywhere in memsets_for_chunk
2378 hash_map<int, uint32> fields_mask_for_chunk;
2379 for (int i = 0; i < descriptor_->field_count(); i++) {
2380 const FieldDescriptor* field = descriptor_->field(i);
2381 if (!field->is_repeated() && !field->containing_oneof()) {
2382 step2_indices.insert(i);
2383 int chunk = i / 8;
2384 fieldname_to_chunk[FieldName(field)] = chunk;
2385 fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
2386 }
2387 }
2388
2389 // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
2390 // The generated code uses two macros to help it clear runs of fields:
2391 // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the
2392 // positions of two fields in the Message.
2393 // ZR_ zeroes a non-empty range of fields via memset.
2394 const char* macros =
2395 "#if defined(__clang__)\n"
2396 "#define ZR_HELPER_(f) \\\n"
2397 " _Pragma(\"clang diagnostic push\") \\\n"
2398 " _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
2399 " __builtin_offsetof($classname$, f) \\\n"
2400 " _Pragma(\"clang diagnostic pop\")\n"
2401 "#else\n"
2402 "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
2403 " &reinterpret_cast<$classname$*>(16)->f)\n"
2404 "#endif\n\n"
2405 "#define ZR_(first, last) do {\\\n"
2406 " ::memset(&(first), 0,\\\n"
2407 " ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
2408 "} while (0)\n\n";
2409 for (int i = 0; i < runs_of_fields_.size(); i++) {
2410 const vector<string>& run = runs_of_fields_[i];
2411 if (run.size() < 2) continue;
2412 const string& first_field_name = run[0];
2413 const string& last_field_name = run.back();
2414 int chunk = fieldname_to_chunk[run[0]];
2415 memsets_for_chunk[chunk].append(
2416 "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
2417 for (int j = 0; j < run.size(); j++) {
2418 GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
2419 handled.insert(run[j]);
2420 }
2421 memset_field_count_for_chunk[chunk] += run.size();
2422 }
2423 const bool macros_are_needed = handled.size() > 0;
2424 if (macros_are_needed) {
2425 printer->Outdent();
2426 printer->Print(macros,
2427 "classname", classname_);
2428 printer->Indent();
2429 }
2430 // Step 2b: Finish step 2, ignoring fields handled in step 2a.
2431 int last_index = -1;
2432 bool chunk_block_in_progress = false;
2433 for (int i = 0; i < descriptor_->field_count(); i++) {
2434 if (step2_indices.count(i) == 0) continue;
2435 const FieldDescriptor* field = descriptor_->field(i);
2436 const string fieldname = FieldName(field);
2437 if (i / 8 != last_index / 8 || last_index < 0) {
2438 // End previous chunk, if there was one.
2439 if (chunk_block_in_progress) {
2440 printer->Outdent();
2441 printer->Print("}\n");
2442 chunk_block_in_progress = false;
2443 }
2444 // Start chunk.
2445 const string& memsets = memsets_for_chunk[i / 8];
2446 uint32 mask = fields_mask_for_chunk[i / 8];
2447 int count = popcnt(mask);
2448 GOOGLE_DCHECK_GE(count, 1);
2449 if (count == 1 ||
2450 (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
2451 // No "if" here because the chunk is trivial.
2452 } else {
2453 if (HasFieldPresence(descriptor_->file())) {
2454 printer->Print(
2455 "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
2456 "index", SimpleItoa(i / 8 * 8),
2457 "mask", SimpleItoa(mask));
2458 printer->Indent();
2459 chunk_block_in_progress = true;
2460 }
2461 }
2462 printer->Print(memsets.c_str());
2463 }
2464 last_index = i;
2465 if (handled.count(fieldname) > 0) continue;
2466
2467 // It's faster to just overwrite primitive types, but we should
2468 // only clear strings and messages if they were set.
2469 // TODO(kenton): Let the CppFieldGenerator decide this somehow.
2470 bool should_check_bit =
2471 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
2472 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
2473
2474 bool have_enclosing_if = false;
2475 if (should_check_bit &&
2476 // If no field presence, then always clear strings/messages as well.
2477 HasFieldPresence(descriptor_->file())) {
2478 printer->Print("if (has_$name$()) {\n", "name", fieldname);
2479 printer->Indent();
2480 have_enclosing_if = true;
2481 }
2482
2483 if (use_dependent_base_ && IsFieldDependent(field)) {
2484 printer->Print("clear_$name$();\n", "name", fieldname);
2485 } else {
2486 field_generators_.get(field).GenerateClearingCode(printer);
2487 }
2488
2489 if (have_enclosing_if) {
2490 printer->Outdent();
2491 printer->Print("}\n");
2492 }
2493 }
2494
2495 if (chunk_block_in_progress) {
2496 printer->Outdent();
2497 printer->Print("}\n");
2498 }
2499 if (macros_are_needed) {
2500 printer->Outdent();
2501 printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n");
2502 printer->Indent();
2503 }
2504
2505 // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
2506 for (int i = 0; i < descriptor_->field_count(); i++) {
2507 const FieldDescriptor* field = descriptor_->field(i);
2508
2509 if (field->is_repeated()) {
2510 if (use_dependent_base_ && IsFieldDependent(field)) {
2511 printer->Print("clear_$name$();\n", "name", FieldName(field));
2512 } else {
2513 field_generators_.get(field).GenerateClearingCode(printer);
2514 }
2515 }
2516 }
2517
2518 // Step 4: Unions.
2519 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2520 printer->Print(
2521 "clear_$oneof_name$();\n",
2522 "oneof_name", descriptor_->oneof_decl(i)->name());
2523 }
2524
2525 if (HasFieldPresence(descriptor_->file())) {
2526 // Step 5: Everything else.
2527 printer->Print(
2528 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
2529 }
2530
2531 if (PreserveUnknownFields(descriptor_)) {
2532 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2533 printer->Print(
2534 "if (_internal_metadata_.have_unknown_fields()) {\n"
2535 " mutable_unknown_fields()->Clear();\n"
2536 "}\n");
2537 } else {
2538 if (SupportsArenas(descriptor_)) {
2539 printer->Print(
2540 "_unknown_fields_.ClearToEmpty(\n"
2541 " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
2542 " GetArenaNoVirtual());\n");
2543 } else {
2544 printer->Print(
2545 "_unknown_fields_.ClearToEmptyNoArena(\n"
2546 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
2547 }
2548 }
2549 }
2550
2551 printer->Outdent();
2552 printer->Print("}\n");
2553 }
2554
2555 void MessageGenerator::
GenerateOneofClear(io::Printer * printer)2556 GenerateOneofClear(io::Printer* printer) {
2557 // Generated function clears the active field and union case (e.g. foo_case_).
2558 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2559 map<string, string> oneof_vars;
2560 oneof_vars["classname"] = classname_;
2561 oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
2562 oneof_vars["full_name"] = descriptor_->full_name();
2563 string message_class;
2564
2565 printer->Print(oneof_vars,
2566 "void $classname$::clear_$oneofname$() {\n"
2567 "// @@protoc_insertion_point(one_of_clear_start:"
2568 "$full_name$)\n");
2569 printer->Indent();
2570 printer->Print(oneof_vars,
2571 "switch($oneofname$_case()) {\n");
2572 printer->Indent();
2573 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2574 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2575 printer->Print(
2576 "case k$field_name$: {\n",
2577 "field_name", UnderscoresToCamelCase(field->name(), true));
2578 printer->Indent();
2579 // We clear only allocated objects in oneofs
2580 if (!IsStringOrMessage(field)) {
2581 printer->Print(
2582 "// No need to clear\n");
2583 } else {
2584 field_generators_.get(field).GenerateClearingCode(printer);
2585 }
2586 printer->Print(
2587 "break;\n");
2588 printer->Outdent();
2589 printer->Print(
2590 "}\n");
2591 }
2592 printer->Print(
2593 "case $cap_oneof_name$_NOT_SET: {\n"
2594 " break;\n"
2595 "}\n",
2596 "cap_oneof_name",
2597 ToUpper(descriptor_->oneof_decl(i)->name()));
2598 printer->Outdent();
2599 printer->Print(
2600 "}\n"
2601 "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
2602 "oneof_index", SimpleItoa(i),
2603 "cap_oneof_name",
2604 ToUpper(descriptor_->oneof_decl(i)->name()));
2605 printer->Outdent();
2606 printer->Print(
2607 "}\n"
2608 "\n");
2609 }
2610 }
2611
2612 void MessageGenerator::
GenerateSwap(io::Printer * printer)2613 GenerateSwap(io::Printer* printer) {
2614 if (SupportsArenas(descriptor_)) {
2615 // Generate the Swap member function. This is a lightweight wrapper around
2616 // UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory
2617 // ownership situation: swapping across arenas or between an arena and a
2618 // heap requires copying.
2619 printer->Print(
2620 "void $classname$::Swap($classname$* other) {\n"
2621 " if (other == this) return;\n"
2622 " if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
2623 " InternalSwap(other);\n"
2624 " } else {\n"
2625 " $classname$ temp;\n"
2626 " temp.MergeFrom(*this);\n"
2627 " CopyFrom(*other);\n"
2628 " other->CopyFrom(temp);\n"
2629 " }\n"
2630 "}\n"
2631 "void $classname$::UnsafeArenaSwap($classname$* other) {\n"
2632 " if (other == this) return;\n"
2633 " GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
2634 " InternalSwap(other);\n"
2635 "}\n",
2636 "classname", classname_);
2637 } else {
2638 printer->Print(
2639 "void $classname$::Swap($classname$* other) {\n"
2640 " if (other == this) return;\n"
2641 " InternalSwap(other);\n"
2642 "}\n",
2643 "classname", classname_);
2644 }
2645
2646 // Generate the UnsafeArenaSwap member function.
2647 printer->Print("void $classname$::InternalSwap($classname$* other) {\n",
2648 "classname", classname_);
2649 printer->Indent();
2650
2651 if (HasGeneratedMethods(descriptor_->file(), options_)) {
2652 for (int i = 0; i < descriptor_->field_count(); i++) {
2653 const FieldDescriptor* field = descriptor_->field(i);
2654 field_generators_.get(field).GenerateSwappingCode(printer);
2655 }
2656
2657 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2658 printer->Print(
2659 "std::swap($oneof_name$_, other->$oneof_name$_);\n"
2660 "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
2661 "oneof_name", descriptor_->oneof_decl(i)->name(),
2662 "i", SimpleItoa(i));
2663 }
2664
2665 if (HasFieldPresence(descriptor_->file())) {
2666 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
2667 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
2668 "i", SimpleItoa(i));
2669 }
2670 }
2671
2672 // Ignore PreserveUnknownFields here - always swap internal_metadata as it
2673 // may contain more than just unknown fields.
2674 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2675 printer->Print(
2676 "_internal_metadata_.Swap(&other->_internal_metadata_);\n");
2677 } else {
2678 printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
2679 }
2680
2681 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
2682 if (descriptor_->extension_range_count() > 0) {
2683 printer->Print("_extensions_.Swap(&other->_extensions_);\n");
2684 }
2685 } else {
2686 printer->Print("GetReflection()->Swap(this, other);");
2687 }
2688
2689 printer->Outdent();
2690 printer->Print("}\n");
2691 }
2692
2693 void MessageGenerator::
GenerateMergeFrom(io::Printer * printer)2694 GenerateMergeFrom(io::Printer* printer) {
2695 if (HasDescriptorMethods(descriptor_->file(), options_)) {
2696 // Generate the generalized MergeFrom (aka that which takes in the Message
2697 // base class as a parameter).
2698 printer->Print(
2699 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
2700 "// @@protoc_insertion_point(generalized_merge_from_start:"
2701 "$full_name$)\n"
2702 " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
2703 "classname", classname_, "full_name", descriptor_->full_name());
2704 printer->Indent();
2705
2706 // Cast the message to the proper type. If we find that the message is
2707 // *not* of the proper type, we can still call Merge via the reflection
2708 // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
2709 // for each message.
2710 printer->Print(
2711 "const $classname$* source = \n"
2712 " ::google::protobuf::internal::DynamicCastToGenerated<const $classname$>(\n"
2713 " &from);\n"
2714 "if (source == NULL) {\n"
2715 "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
2716 "$full_name$)\n"
2717 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
2718 "} else {\n"
2719 "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
2720 "$full_name$)\n"
2721 " MergeFrom(*source);\n"
2722 "}\n",
2723 "classname", classname_, "full_name", descriptor_->full_name());
2724
2725 printer->Outdent();
2726 printer->Print("}\n\n");
2727 } else {
2728 // Generate CheckTypeAndMergeFrom().
2729 printer->Print(
2730 "void $classname$::CheckTypeAndMergeFrom(\n"
2731 " const ::google::protobuf::MessageLite& from) {\n"
2732 " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
2733 "}\n"
2734 "\n",
2735 "classname", classname_);
2736 }
2737
2738 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
2739 printer->Print(
2740 "void $classname$::MergeFrom(const $classname$& from) {\n"
2741 "// @@protoc_insertion_point(class_specific_merge_from_start:"
2742 "$full_name$)\n"
2743 " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
2744 "classname", classname_, "full_name", descriptor_->full_name());
2745 printer->Indent();
2746
2747 // Merge Repeated fields. These fields do not require a
2748 // check as we can simply iterate over them.
2749 for (int i = 0; i < descriptor_->field_count(); ++i) {
2750 const FieldDescriptor* field = descriptor_->field(i);
2751
2752 if (field->is_repeated()) {
2753 field_generators_.get(field).GenerateMergingCode(printer);
2754 }
2755 }
2756
2757 // Merge oneof fields. Oneof field requires oneof case check.
2758 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
2759 printer->Print(
2760 "switch (from.$oneofname$_case()) {\n",
2761 "oneofname", descriptor_->oneof_decl(i)->name());
2762 printer->Indent();
2763 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2764 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2765 printer->Print(
2766 "case k$field_name$: {\n",
2767 "field_name", UnderscoresToCamelCase(field->name(), true));
2768 printer->Indent();
2769 field_generators_.get(field).GenerateMergingCode(printer);
2770 printer->Print(
2771 "break;\n");
2772 printer->Outdent();
2773 printer->Print(
2774 "}\n");
2775 }
2776 printer->Print(
2777 "case $cap_oneof_name$_NOT_SET: {\n"
2778 " break;\n"
2779 "}\n",
2780 "cap_oneof_name",
2781 ToUpper(descriptor_->oneof_decl(i)->name()));
2782 printer->Outdent();
2783 printer->Print(
2784 "}\n");
2785 }
2786
2787 // Merge Optional and Required fields (after a _has_bit check).
2788 int last_index = -1;
2789
2790 for (int i = 0; i < descriptor_->field_count(); ++i) {
2791 const FieldDescriptor* field = descriptor_->field(i);
2792
2793 if (!field->is_repeated() && !field->containing_oneof()) {
2794 if (HasFieldPresence(descriptor_->file())) {
2795 // See above in GenerateClear for an explanation of this.
2796 if (i / 8 != last_index / 8 || last_index < 0) {
2797 if (last_index >= 0) {
2798 printer->Outdent();
2799 printer->Print("}\n");
2800 }
2801 printer->Print(
2802 "if (from._has_bits_[$index$ / 32] & "
2803 "(0xffu << ($index$ % 32))) {\n",
2804 "index", SimpleItoa(field->index()));
2805 printer->Indent();
2806 }
2807 }
2808
2809 last_index = i;
2810
2811 bool have_enclosing_if = false;
2812 if (HasFieldPresence(descriptor_->file())) {
2813 printer->Print(
2814 "if (from.has_$name$()) {\n",
2815 "name", FieldName(field));
2816 printer->Indent();
2817 have_enclosing_if = true;
2818 } else {
2819 // Merge semantics without true field presence: primitive fields are
2820 // merged only if non-zero (numeric) or non-empty (string).
2821 have_enclosing_if = EmitFieldNonDefaultCondition(
2822 printer, "from.", field);
2823 }
2824
2825 field_generators_.get(field).GenerateMergingCode(printer);
2826
2827 if (have_enclosing_if) {
2828 printer->Outdent();
2829 printer->Print("}\n");
2830 }
2831 }
2832 }
2833
2834 if (HasFieldPresence(descriptor_->file()) &&
2835 last_index >= 0) {
2836 printer->Outdent();
2837 printer->Print("}\n");
2838 }
2839
2840 if (descriptor_->extension_range_count() > 0) {
2841 printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
2842 }
2843
2844 if (PreserveUnknownFields(descriptor_)) {
2845 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2846 printer->Print(
2847 "if (from._internal_metadata_.have_unknown_fields()) {\n"
2848 " mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"
2849 "}\n");
2850 } else {
2851 printer->Print(
2852 "if (!from.unknown_fields().empty()) {\n"
2853 " mutable_unknown_fields()->append(from.unknown_fields());\n"
2854 "}\n");
2855 }
2856 }
2857
2858 printer->Outdent();
2859 printer->Print("}\n");
2860 }
2861
2862 void MessageGenerator::
GenerateCopyFrom(io::Printer * printer)2863 GenerateCopyFrom(io::Printer* printer) {
2864 if (HasDescriptorMethods(descriptor_->file(), options_)) {
2865 // Generate the generalized CopyFrom (aka that which takes in the Message
2866 // base class as a parameter).
2867 printer->Print(
2868 "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n"
2869 "// @@protoc_insertion_point(generalized_copy_from_start:"
2870 "$full_name$)\n",
2871 "classname", classname_, "full_name", descriptor_->full_name());
2872 printer->Indent();
2873
2874 printer->Print(
2875 "if (&from == this) return;\n"
2876 "Clear();\n"
2877 "MergeFrom(from);\n");
2878
2879 printer->Outdent();
2880 printer->Print("}\n\n");
2881 }
2882
2883 // Generate the class-specific CopyFrom.
2884 printer->Print(
2885 "void $classname$::CopyFrom(const $classname$& from) {\n"
2886 "// @@protoc_insertion_point(class_specific_copy_from_start:"
2887 "$full_name$)\n",
2888 "classname", classname_, "full_name", descriptor_->full_name());
2889 printer->Indent();
2890
2891 printer->Print(
2892 "if (&from == this) return;\n"
2893 "Clear();\n"
2894 "MergeFrom(from);\n");
2895
2896 printer->Outdent();
2897 printer->Print("}\n");
2898 }
2899
2900 void MessageGenerator::
GenerateMergeFromCodedStream(io::Printer * printer)2901 GenerateMergeFromCodedStream(io::Printer* printer) {
2902 if (descriptor_->options().message_set_wire_format()) {
2903 // Special-case MessageSet.
2904 printer->Print(
2905 "bool $classname$::MergePartialFromCodedStream(\n"
2906 " ::google::protobuf::io::CodedInputStream* input) {\n",
2907 "classname", classname_);
2908
2909 PrintHandlingOptionalStaticInitializers(
2910 descriptor_->file(), options_, printer,
2911 // With static initializers.
2912 " return _extensions_.ParseMessageSet(input, default_instance_,\n"
2913 " mutable_unknown_fields());\n",
2914 // Without.
2915 " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
2916 " mutable_unknown_fields());\n",
2917 // Vars.
2918 "classname", classname_);
2919
2920 printer->Print(
2921 "}\n");
2922 return;
2923 }
2924
2925 printer->Print(
2926 "bool $classname$::MergePartialFromCodedStream(\n"
2927 " ::google::protobuf::io::CodedInputStream* input) {\n"
2928 "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n"
2929 " ::google::protobuf::uint32 tag;\n",
2930 "classname", classname_);
2931
2932 if (PreserveUnknownFields(descriptor_) &&
2933 !UseUnknownFieldSet(descriptor_->file(), options_)) {
2934 // Use LazyStringOutputString to avoid initializing unknown fields string
2935 // unless it is actually needed. For the same reason, disable eager refresh
2936 // on the CodedOutputStream.
2937 printer->Print(
2938 " ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
2939 " ::google::protobuf::internal::NewPermanentCallback(\n"
2940 " &MutableUnknownFieldsFor$classname$, this));\n"
2941 " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
2942 " &unknown_fields_string, false);\n",
2943 "classname", classname_);
2944 }
2945
2946 printer->Print(
2947 " // @@protoc_insertion_point(parse_start:$full_name$)\n",
2948 "full_name", descriptor_->full_name());
2949
2950 printer->Indent();
2951 printer->Print("for (;;) {\n");
2952 printer->Indent();
2953
2954 google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
2955 SortFieldsByNumber(descriptor_));
2956 uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
2957 WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
2958 const int kCutoff0 = 127; // fits in 1-byte varint
2959 const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint
2960 printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
2961 "input->ReadTagWithCutoff($max$);\n"
2962 "tag = p.first;\n"
2963 "if (!p.second) goto handle_unusual;\n",
2964 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
2965 (maxtag <= kCutoff1 ? kCutoff1 :
2966 maxtag)));
2967 if (descriptor_->field_count() > 0) {
2968 // We don't even want to print the switch() if we have no fields because
2969 // MSVC dislikes switch() statements that contain only a default value.
2970
2971 // Note: If we just switched on the tag rather than the field number, we
2972 // could avoid the need for the if() to check the wire type at the beginning
2973 // of each case. However, this is actually a bit slower in practice as it
2974 // creates a jump table that is 8x larger and sparser, and meanwhile the
2975 // if()s are highly predictable.
2976 printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
2977 "GetTagFieldNumber(tag)) {\n");
2978
2979 printer->Indent();
2980
2981 // Find repeated messages and groups now, to simplify what follows.
2982 hash_set<int> fields_with_parse_loop;
2983 for (int i = 0; i < descriptor_->field_count(); i++) {
2984 const FieldDescriptor* field = ordered_fields[i];
2985 if (field->is_repeated() &&
2986 (field->type() == FieldDescriptor::TYPE_MESSAGE ||
2987 field->type() == FieldDescriptor::TYPE_GROUP)) {
2988 fields_with_parse_loop.insert(i);
2989 }
2990 }
2991
2992 // need_label is true if we generated "goto parse_$name$" while handling the
2993 // previous field.
2994 bool need_label = false;
2995 for (int i = 0; i < descriptor_->field_count(); i++) {
2996 const FieldDescriptor* field = ordered_fields[i];
2997 const bool loops = fields_with_parse_loop.count(i) > 0;
2998 const bool next_field_loops = fields_with_parse_loop.count(i + 1) > 0;
2999
3000 PrintFieldComment(printer, field);
3001
3002 printer->Print(
3003 "case $number$: {\n",
3004 "number", SimpleItoa(field->number()));
3005 printer->Indent();
3006 const FieldGenerator& field_generator = field_generators_.get(field);
3007
3008 // Emit code to parse the common, expected case.
3009 printer->Print("if (tag == $commontag$) {\n",
3010 "commontag", SimpleItoa(WireFormat::MakeTag(field)));
3011
3012 if (need_label ||
3013 (field->is_repeated() && !field->is_packed() && !loops)) {
3014 printer->Print(
3015 " parse_$name$:\n",
3016 "name", field->name());
3017 }
3018 if (loops) {
3019 printer->Print(
3020 " DO_(input->IncrementRecursionDepth());\n"
3021 " parse_loop_$name$:\n",
3022 "name", field->name());
3023 }
3024
3025 printer->Indent();
3026 if (field->is_packed()) {
3027 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
3028 } else {
3029 field_generator.GenerateMergeFromCodedStream(printer);
3030 }
3031 printer->Outdent();
3032
3033 // Emit code to parse unexpectedly packed or unpacked values.
3034 if (field->is_packed()) {
3035 internal::WireFormatLite::WireType wiretype =
3036 WireFormat::WireTypeForFieldType(field->type());
3037 printer->Print("} else if (tag == $uncommontag$) {\n",
3038 "uncommontag", SimpleItoa(
3039 internal::WireFormatLite::MakeTag(
3040 field->number(), wiretype)));
3041 printer->Indent();
3042 field_generator.GenerateMergeFromCodedStream(printer);
3043 printer->Outdent();
3044 } else if (field->is_packable() && !field->is_packed()) {
3045 internal::WireFormatLite::WireType wiretype =
3046 internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
3047 printer->Print("} else if (tag == $uncommontag$) {\n",
3048 "uncommontag", SimpleItoa(
3049 internal::WireFormatLite::MakeTag(
3050 field->number(), wiretype)));
3051 printer->Indent();
3052 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
3053 printer->Outdent();
3054 }
3055
3056 printer->Print(
3057 "} else {\n"
3058 " goto handle_unusual;\n"
3059 "}\n");
3060
3061 // switch() is slow since it can't be predicted well. Insert some if()s
3062 // here that attempt to predict the next tag.
3063 // For non-packed repeated fields, expect the same tag again.
3064 if (loops) {
3065 printer->Print(
3066 "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n",
3067 "tag", SimpleItoa(WireFormat::MakeTag(field)),
3068 "name", field->name());
3069 } else if (field->is_repeated() && !field->is_packed()) {
3070 printer->Print(
3071 "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
3072 "tag", SimpleItoa(WireFormat::MakeTag(field)),
3073 "name", field->name());
3074 }
3075
3076 // Have we emitted "if (input->ExpectTag($next_tag$)) ..." yet?
3077 bool emitted_goto_next_tag = false;
3078
3079 // For repeated messages/groups, we need to decrement recursion depth,
3080 // unless the next tag is also for a repeated message/group.
3081 if (loops) {
3082 if (next_field_loops) {
3083 const FieldDescriptor* next_field = ordered_fields[i + 1];
3084 printer->Print(
3085 "if (input->ExpectTag($next_tag$)) goto parse_loop_$next_name$;\n",
3086 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
3087 "next_name", next_field->name());
3088 emitted_goto_next_tag = true;
3089 }
3090 printer->Print(
3091 "input->UnsafeDecrementRecursionDepth();\n");
3092 }
3093
3094 // If there are more fields, expect the next one.
3095 need_label = false;
3096 if (!emitted_goto_next_tag) {
3097 if (i + 1 == descriptor_->field_count()) {
3098 // Expect EOF.
3099 // TODO(kenton): Expect group end-tag?
3100 printer->Print(
3101 "if (input->ExpectAtEnd()) goto success;\n");
3102 } else {
3103 const FieldDescriptor* next_field = ordered_fields[i + 1];
3104 printer->Print(
3105 "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
3106 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
3107 "next_name", next_field->name());
3108 need_label = true;
3109 }
3110 }
3111
3112 printer->Print(
3113 "break;\n");
3114
3115 printer->Outdent();
3116 printer->Print("}\n\n");
3117 }
3118
3119 printer->Print("default: {\n");
3120 printer->Indent();
3121 }
3122
3123 printer->Outdent();
3124 printer->Print("handle_unusual:\n");
3125 printer->Indent();
3126 // If tag is 0 or an end-group tag then this must be the end of the message.
3127 printer->Print(
3128 "if (tag == 0 ||\n"
3129 " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
3130 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
3131 " goto success;\n"
3132 "}\n");
3133
3134 // Handle extension ranges.
3135 if (descriptor_->extension_range_count() > 0) {
3136 printer->Print(
3137 "if (");
3138 for (int i = 0; i < descriptor_->extension_range_count(); i++) {
3139 const Descriptor::ExtensionRange* range =
3140 descriptor_->extension_range(i);
3141 if (i > 0) printer->Print(" ||\n ");
3142
3143 uint32 start_tag = WireFormatLite::MakeTag(
3144 range->start, static_cast<WireFormatLite::WireType>(0));
3145 uint32 end_tag = WireFormatLite::MakeTag(
3146 range->end, static_cast<WireFormatLite::WireType>(0));
3147
3148 if (range->end > FieldDescriptor::kMaxNumber) {
3149 printer->Print(
3150 "($start$u <= tag)",
3151 "start", SimpleItoa(start_tag));
3152 } else {
3153 printer->Print(
3154 "($start$u <= tag && tag < $end$u)",
3155 "start", SimpleItoa(start_tag),
3156 "end", SimpleItoa(end_tag));
3157 }
3158 }
3159 printer->Print(") {\n");
3160 if (PreserveUnknownFields(descriptor_)) {
3161 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3162 PrintHandlingOptionalStaticInitializers(
3163 descriptor_->file(), options_, printer,
3164 // With static initializers.
3165 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
3166 " mutable_unknown_fields()));\n",
3167 // Without.
3168 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
3169 " mutable_unknown_fields()));\n");
3170 } else {
3171 PrintHandlingOptionalStaticInitializers(
3172 descriptor_->file(), options_, printer,
3173 // With static initializers.
3174 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
3175 " &unknown_fields_stream));\n",
3176 // Without.
3177 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
3178 " &unknown_fields_stream));\n");
3179 }
3180 } else {
3181 PrintHandlingOptionalStaticInitializers(
3182 descriptor_->file(), options_, printer,
3183 // With static initializers.
3184 " DO_(_extensions_.ParseField(tag, input, default_instance_);\n",
3185 // Without.
3186 " DO_(_extensions_.ParseField(tag, input, &default_instance());\n");
3187 }
3188 printer->Print(
3189 " continue;\n"
3190 "}\n");
3191 }
3192
3193 // We really don't recognize this tag. Skip it.
3194 if (PreserveUnknownFields(descriptor_)) {
3195 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3196 printer->Print(
3197 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
3198 " input, tag, mutable_unknown_fields()));\n");
3199 } else {
3200 printer->Print(
3201 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
3202 " input, tag, &unknown_fields_stream));\n");
3203 }
3204 } else {
3205 printer->Print(
3206 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
3207 }
3208
3209 if (descriptor_->field_count() > 0) {
3210 printer->Print("break;\n");
3211 printer->Outdent();
3212 printer->Print("}\n"); // default:
3213 printer->Outdent();
3214 printer->Print("}\n"); // switch
3215 }
3216
3217 printer->Outdent();
3218 printer->Outdent();
3219 printer->Print(
3220 " }\n" // for (;;)
3221 "success:\n"
3222 " // @@protoc_insertion_point(parse_success:$full_name$)\n"
3223 " return true;\n"
3224 "failure:\n"
3225 " // @@protoc_insertion_point(parse_failure:$full_name$)\n"
3226 " return false;\n"
3227 "#undef DO_\n"
3228 "}\n", "full_name", descriptor_->full_name());
3229 }
3230
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field,bool to_array)3231 void MessageGenerator::GenerateSerializeOneField(
3232 io::Printer* printer, const FieldDescriptor* field, bool to_array) {
3233 PrintFieldComment(printer, field);
3234
3235 bool have_enclosing_if = false;
3236 if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) {
3237 printer->Print(
3238 "if (has_$name$()) {\n",
3239 "name", FieldName(field));
3240 printer->Indent();
3241 have_enclosing_if = true;
3242 } else if (!HasFieldPresence(descriptor_->file())) {
3243 have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
3244 }
3245
3246 if (to_array) {
3247 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
3248 printer);
3249 } else {
3250 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
3251 }
3252
3253 if (have_enclosing_if) {
3254 printer->Outdent();
3255 printer->Print("}\n");
3256 }
3257 printer->Print("\n");
3258 }
3259
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range,bool to_array)3260 void MessageGenerator::GenerateSerializeOneExtensionRange(
3261 io::Printer* printer, const Descriptor::ExtensionRange* range,
3262 bool to_array) {
3263 map<string, string> vars;
3264 vars["start"] = SimpleItoa(range->start);
3265 vars["end"] = SimpleItoa(range->end);
3266 printer->Print(vars,
3267 "// Extension range [$start$, $end$)\n");
3268 if (to_array) {
3269 printer->Print(vars,
3270 "target = _extensions_.SerializeWithCachedSizesToArray(\n"
3271 " $start$, $end$, target);\n\n");
3272 } else {
3273 printer->Print(vars,
3274 "_extensions_.SerializeWithCachedSizes(\n"
3275 " $start$, $end$, output);\n\n");
3276 }
3277 }
3278
3279 void MessageGenerator::
GenerateSerializeWithCachedSizes(io::Printer * printer)3280 GenerateSerializeWithCachedSizes(io::Printer* printer) {
3281 if (descriptor_->options().message_set_wire_format()) {
3282 // Special-case MessageSet.
3283 printer->Print(
3284 "void $classname$::SerializeWithCachedSizes(\n"
3285 " ::google::protobuf::io::CodedOutputStream* output) const {\n"
3286 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
3287 "classname", classname_);
3288 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3289 printer->Print(
3290 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
3291 " unknown_fields(), output);\n");
3292 printer->Print(
3293 "}\n");
3294 return;
3295 }
3296
3297 printer->Print(
3298 "void $classname$::SerializeWithCachedSizes(\n"
3299 " ::google::protobuf::io::CodedOutputStream* output) const {\n",
3300 "classname", classname_);
3301 printer->Indent();
3302
3303 printer->Print(
3304 "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
3305 "full_name", descriptor_->full_name());
3306
3307 GenerateSerializeWithCachedSizesBody(printer, false);
3308
3309 printer->Print(
3310 "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
3311 "full_name", descriptor_->full_name());
3312
3313 printer->Outdent();
3314 printer->Print(
3315 "}\n");
3316 }
3317
3318 void MessageGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer * printer)3319 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
3320 if (descriptor_->options().message_set_wire_format()) {
3321 // Special-case MessageSet.
3322 printer->Print(
3323 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
3324 " ::google::protobuf::uint8* target) const {\n"
3325 " target =\n"
3326 " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
3327 "classname", classname_);
3328 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3329 printer->Print(
3330 " target = ::google::protobuf::internal::WireFormat::\n"
3331 " SerializeUnknownMessageSetItemsToArray(\n"
3332 " unknown_fields(), target);\n");
3333 printer->Print(
3334 " return target;\n"
3335 "}\n");
3336 return;
3337 }
3338
3339 printer->Print(
3340 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
3341 " ::google::protobuf::uint8* target) const {\n",
3342 "classname", classname_);
3343 printer->Indent();
3344
3345 printer->Print(
3346 "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
3347 "full_name", descriptor_->full_name());
3348
3349 GenerateSerializeWithCachedSizesBody(printer, true);
3350
3351 printer->Print(
3352 "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
3353 "full_name", descriptor_->full_name());
3354
3355 printer->Outdent();
3356 printer->Print(
3357 " return target;\n"
3358 "}\n");
3359 }
3360
3361 void MessageGenerator::
GenerateSerializeWithCachedSizesBody(io::Printer * printer,bool to_array)3362 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
3363 google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
3364 SortFieldsByNumber(descriptor_));
3365
3366 vector<const Descriptor::ExtensionRange*> sorted_extensions;
3367 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
3368 sorted_extensions.push_back(descriptor_->extension_range(i));
3369 }
3370 std::sort(sorted_extensions.begin(), sorted_extensions.end(),
3371 ExtensionRangeSorter());
3372
3373 // Merge the fields and the extension ranges, both sorted by field number.
3374 int i, j;
3375 for (i = 0, j = 0;
3376 i < descriptor_->field_count() || j < sorted_extensions.size();
3377 ) {
3378 if (i == descriptor_->field_count()) {
3379 GenerateSerializeOneExtensionRange(printer,
3380 sorted_extensions[j++],
3381 to_array);
3382 } else if (j == sorted_extensions.size()) {
3383 GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
3384 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
3385 GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
3386 } else {
3387 GenerateSerializeOneExtensionRange(printer,
3388 sorted_extensions[j++],
3389 to_array);
3390 }
3391 }
3392
3393 if (PreserveUnknownFields(descriptor_)) {
3394 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3395 printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n");
3396 printer->Indent();
3397 if (to_array) {
3398 printer->Print(
3399 "target = "
3400 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
3401 " unknown_fields(), target);\n");
3402 } else {
3403 printer->Print(
3404 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
3405 " unknown_fields(), output);\n");
3406 }
3407 printer->Outdent();
3408
3409 printer->Print(
3410 "}\n");
3411 } else {
3412 printer->Print(
3413 "output->WriteRaw(unknown_fields().data(),\n"
3414 " static_cast<int>(unknown_fields().size()));\n");
3415 }
3416 }
3417 }
3418
RequiredFieldsBitMask(const Descriptor * desc)3419 static vector<uint32> RequiredFieldsBitMask(const Descriptor* desc) {
3420 vector<uint32> result;
3421 uint32 mask = 0;
3422 for (int i = 0; i < desc->field_count(); i++) {
3423 if (i > 0 && i % 32 == 0) {
3424 result.push_back(mask);
3425 mask = 0;
3426 }
3427 if (desc->field(i)->is_required()) {
3428 mask |= (1 << (i & 31));
3429 }
3430 }
3431 if (mask != 0) {
3432 result.push_back(mask);
3433 }
3434 return result;
3435 }
3436
3437 // Create an expression that evaluates to
3438 // "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
3439 // masks is allowed to be shorter than _has_bits_, but at least one element of
3440 // masks must be non-zero.
ConditionalToCheckBitmasks(const vector<uint32> & masks)3441 static string ConditionalToCheckBitmasks(const vector<uint32>& masks) {
3442 vector<string> parts;
3443 for (int i = 0; i < masks.size(); i++) {
3444 if (masks[i] == 0) continue;
3445 string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
3446 // Each xor evaluates to 0 if the expected bits are present.
3447 parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
3448 }
3449 GOOGLE_CHECK(!parts.empty());
3450 // If we have multiple parts, each expected to be 0, then bitwise-or them.
3451 string result = parts.size() == 1 ? parts[0] :
3452 StrCat("(", Join(parts, "\n | "), ")");
3453 return result + " == 0";
3454 }
3455
3456 void MessageGenerator::
GenerateByteSize(io::Printer * printer)3457 GenerateByteSize(io::Printer* printer) {
3458 if (descriptor_->options().message_set_wire_format()) {
3459 // Special-case MessageSet.
3460 printer->Print(
3461 "int $classname$::ByteSize() const {\n"
3462 "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
3463 " int total_size = _extensions_.MessageSetByteSize();\n",
3464 "classname", classname_, "full_name", descriptor_->full_name());
3465 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3466 printer->Print(
3467 "if (_internal_metadata_.have_unknown_fields()) {\n"
3468 " total_size += ::google::protobuf::internal::WireFormat::\n"
3469 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"
3470 "}\n");
3471 printer->Print(
3472 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
3473 " _cached_size_ = total_size;\n"
3474 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
3475 " return total_size;\n"
3476 "}\n");
3477 return;
3478 }
3479
3480 if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
3481 // Emit a function (rarely used, we hope) that handles the required fields
3482 // by checking for each one individually.
3483 printer->Print(
3484 "int $classname$::RequiredFieldsByteSizeFallback() const {\n"
3485 "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
3486 "$full_name$)\n",
3487 "classname", classname_, "full_name", descriptor_->full_name());
3488 printer->Indent();
3489 printer->Print("int total_size = 0;\n");
3490 for (int i = 0; i < descriptor_->field_count(); i++) {
3491 const FieldDescriptor* field = descriptor_->field(i);
3492 if (field->is_required()) {
3493 printer->Print("\n"
3494 "if (has_$name$()) {\n",
3495 "name", FieldName(field));
3496 printer->Indent();
3497 PrintFieldComment(printer, field);
3498 field_generators_.get(field).GenerateByteSize(printer);
3499 printer->Outdent();
3500 printer->Print("}\n");
3501 }
3502 }
3503 printer->Print("\n"
3504 "return total_size;\n");
3505 printer->Outdent();
3506 printer->Print("}\n");
3507 }
3508
3509 printer->Print(
3510 "int $classname$::ByteSize() const {\n"
3511 "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n",
3512 "classname", classname_, "full_name", descriptor_->full_name());
3513 printer->Indent();
3514 printer->Print(
3515 "int total_size = 0;\n"
3516 "\n");
3517
3518 // Handle required fields (if any). We expect all of them to be
3519 // present, so emit one conditional that checks for that. If they are all
3520 // present then the fast path executes; otherwise the slow path executes.
3521 if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
3522 // The fast path works if all required fields are present.
3523 vector<uint32> masks_for_has_bits = RequiredFieldsBitMask(descriptor_);
3524 printer->Print((string("if (") +
3525 ConditionalToCheckBitmasks(masks_for_has_bits) +
3526 ") { // All required fields are present.\n").c_str());
3527 printer->Indent();
3528 for (int i = 0; i < descriptor_->field_count(); i++) {
3529 const FieldDescriptor* field = descriptor_->field(i);
3530 if (!field->is_required()) continue;
3531 PrintFieldComment(printer, field);
3532 field_generators_.get(field).GenerateByteSize(printer);
3533 printer->Print("\n");
3534 }
3535 printer->Outdent();
3536 printer->Print("} else {\n" // the slow path
3537 " total_size += RequiredFieldsByteSizeFallback();\n"
3538 "}\n");
3539 } else {
3540 // num_required_fields_ <= 1: no need to be tricky
3541 for (int i = 0; i < descriptor_->field_count(); i++) {
3542 const FieldDescriptor* field = descriptor_->field(i);
3543 if (!field->is_required()) continue;
3544 PrintFieldComment(printer, field);
3545 printer->Print("if (has_$name$()) {\n",
3546 "name", FieldName(field));
3547 printer->Indent();
3548 field_generators_.get(field).GenerateByteSize(printer);
3549 printer->Outdent();
3550 printer->Print("}\n");
3551 }
3552 }
3553
3554 // Handle optional fields (worry below about repeateds, oneofs, etc.).
3555 // These are handled in chunks of 8. The first chunk is
3556 // the non-requireds-non-repeateds-non-unions-non-extensions in
3557 // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
3558 // and the second chunk is the same for
3559 // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
3560 // etc.
3561 hash_map<int, uint32> fields_mask_for_chunk;
3562 for (int i = 0; i < descriptor_->field_count(); i++) {
3563 const FieldDescriptor* field = descriptor_->field(i);
3564 if (!field->is_required() && !field->is_repeated() &&
3565 !field->containing_oneof()) {
3566 fields_mask_for_chunk[i / 8] |= static_cast<uint32>(1) << (i % 32);
3567 }
3568 }
3569
3570 int last_index = -1;
3571 bool chunk_block_in_progress = false;
3572 for (int i = 0; i < descriptor_->field_count(); i++) {
3573 const FieldDescriptor* field = descriptor_->field(i);
3574 if (!field->is_required() && !field->is_repeated() &&
3575 !field->containing_oneof()) {
3576 // See above in GenerateClear for an explanation of this.
3577 // TODO(kenton): Share code? Unclear how to do so without
3578 // over-engineering.
3579 if (i / 8 != last_index / 8 || last_index < 0) {
3580 // End previous chunk, if there was one.
3581 if (chunk_block_in_progress) {
3582 printer->Outdent();
3583 printer->Print("}\n");
3584 chunk_block_in_progress = false;
3585 }
3586 // Start chunk.
3587 uint32 mask = fields_mask_for_chunk[i / 8];
3588 int count = popcnt(mask);
3589 GOOGLE_DCHECK_GE(count, 1);
3590 if (count == 1) {
3591 // No "if" here because the chunk is trivial.
3592 } else {
3593 if (HasFieldPresence(descriptor_->file())) {
3594 printer->Print(
3595 "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
3596 "index", SimpleItoa(i),
3597 "mask", SimpleItoa(mask));
3598 printer->Indent();
3599 chunk_block_in_progress = true;
3600 }
3601 }
3602 }
3603 last_index = i;
3604
3605 PrintFieldComment(printer, field);
3606
3607 bool have_enclosing_if = false;
3608 if (HasFieldPresence(descriptor_->file())) {
3609 printer->Print(
3610 "if (has_$name$()) {\n",
3611 "name", FieldName(field));
3612 printer->Indent();
3613 have_enclosing_if = true;
3614 } else {
3615 // Without field presence: field is serialized only if it has a
3616 // non-default value.
3617 have_enclosing_if = EmitFieldNonDefaultCondition(
3618 printer, "this->", field);
3619 }
3620
3621 field_generators_.get(field).GenerateByteSize(printer);
3622
3623 if (have_enclosing_if) {
3624 printer->Outdent();
3625 printer->Print(
3626 "}\n"
3627 "\n");
3628 }
3629 }
3630 }
3631
3632 if (chunk_block_in_progress) {
3633 printer->Outdent();
3634 printer->Print("}\n");
3635 }
3636
3637 // Repeated fields don't use _has_bits_ so we count them in a separate
3638 // pass.
3639 for (int i = 0; i < descriptor_->field_count(); i++) {
3640 const FieldDescriptor* field = descriptor_->field(i);
3641
3642 if (field->is_repeated()) {
3643 PrintFieldComment(printer, field);
3644 field_generators_.get(field).GenerateByteSize(printer);
3645 printer->Print("\n");
3646 }
3647 }
3648
3649 // Fields inside a oneof don't use _has_bits_ so we count them in a separate
3650 // pass.
3651 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
3652 printer->Print(
3653 "switch ($oneofname$_case()) {\n",
3654 "oneofname", descriptor_->oneof_decl(i)->name());
3655 printer->Indent();
3656 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
3657 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
3658 PrintFieldComment(printer, field);
3659 printer->Print(
3660 "case k$field_name$: {\n",
3661 "field_name", UnderscoresToCamelCase(field->name(), true));
3662 printer->Indent();
3663 field_generators_.get(field).GenerateByteSize(printer);
3664 printer->Print(
3665 "break;\n");
3666 printer->Outdent();
3667 printer->Print(
3668 "}\n");
3669 }
3670 printer->Print(
3671 "case $cap_oneof_name$_NOT_SET: {\n"
3672 " break;\n"
3673 "}\n",
3674 "cap_oneof_name",
3675 ToUpper(descriptor_->oneof_decl(i)->name()));
3676 printer->Outdent();
3677 printer->Print(
3678 "}\n");
3679 }
3680
3681 if (descriptor_->extension_range_count() > 0) {
3682 printer->Print(
3683 "total_size += _extensions_.ByteSize();\n"
3684 "\n");
3685 }
3686
3687 if (PreserveUnknownFields(descriptor_)) {
3688 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3689 printer->Print(
3690 "if (_internal_metadata_.have_unknown_fields()) {\n"
3691 " total_size +=\n"
3692 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
3693 " unknown_fields());\n"
3694 "}\n");
3695 } else {
3696 printer->Print(
3697 "total_size += unknown_fields().size();\n"
3698 "\n");
3699 }
3700 }
3701
3702 // We update _cached_size_ even though this is a const method. In theory,
3703 // this is not thread-compatible, because concurrent writes have undefined
3704 // results. In practice, since any concurrent writes will be writing the
3705 // exact same value, it works on all common processors. In a future version
3706 // of C++, _cached_size_ should be made into an atomic<int>.
3707 printer->Print(
3708 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
3709 "_cached_size_ = total_size;\n"
3710 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
3711 "return total_size;\n");
3712
3713 printer->Outdent();
3714 printer->Print("}\n");
3715 }
3716
3717 void MessageGenerator::
GenerateIsInitialized(io::Printer * printer)3718 GenerateIsInitialized(io::Printer* printer) {
3719 printer->Print(
3720 "bool $classname$::IsInitialized() const {\n",
3721 "classname", classname_);
3722 printer->Indent();
3723
3724 if (HasFieldPresence(descriptor_->file())) {
3725 // Check that all required fields in this message are set. We can do this
3726 // most efficiently by checking 32 "has bits" at a time.
3727 int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
3728 for (int i = 0; i < has_bits_array_size; i++) {
3729 uint32 mask = 0;
3730 for (int bit = 0; bit < 32; bit++) {
3731 int index = i * 32 + bit;
3732 if (index >= descriptor_->field_count()) break;
3733 const FieldDescriptor* field = descriptor_->field(index);
3734
3735 if (field->is_required()) {
3736 mask |= 1 << bit;
3737 }
3738 }
3739
3740 if (mask != 0) {
3741 printer->Print(
3742 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
3743 "i", SimpleItoa(i),
3744 "mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));
3745 }
3746 }
3747 }
3748
3749 // Now check that all embedded messages are initialized.
3750 printer->Print("\n");
3751 for (int i = 0; i < descriptor_->field_count(); i++) {
3752 const FieldDescriptor* field = descriptor_->field(i);
3753 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
3754 !ShouldIgnoreRequiredFieldCheck(field, options_) &&
3755 HasRequiredFields(field->message_type(), options_)) {
3756 if (field->is_repeated()) {
3757 printer->Print(
3758 "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
3759 " return false;\n",
3760 "name", FieldName(field));
3761 } else {
3762 if (field->options().weak() || !field->containing_oneof()) {
3763 // For weak fields, use the data member (::google::protobuf::Message*) instead
3764 // of the getter to avoid a link dependency on the weak message type
3765 // which is only forward declared.
3766 printer->Print(
3767 "if (has_$name$()) {\n"
3768 " if (!this->$name$_->IsInitialized()) return false;\n"
3769 "}\n",
3770 "name", FieldName(field));
3771 } else {
3772 printer->Print(
3773 "if (has_$name$()) {\n"
3774 " if (!this->$name$().IsInitialized()) return false;\n"
3775 "}\n",
3776 "name", FieldName(field));
3777 }
3778 }
3779 }
3780 }
3781
3782 if (descriptor_->extension_range_count() > 0) {
3783 printer->Print(
3784 "\n"
3785 "if (!_extensions_.IsInitialized()) return false;");
3786 }
3787
3788 printer->Outdent();
3789 printer->Print(
3790 " return true;\n"
3791 "}\n");
3792 }
3793
3794
3795 } // namespace cpp
3796 } // namespace compiler
3797 } // namespace protobuf
3798 } // namespace google
3799