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