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