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#include <set> 40#include <utility> 41#include <vector> 42#include <google/protobuf/compiler/cpp/cpp_message.h> 43#include <google/protobuf/compiler/cpp/cpp_field.h> 44#include <google/protobuf/compiler/cpp/cpp_enum.h> 45#include <google/protobuf/compiler/cpp/cpp_extension.h> 46#include <google/protobuf/compiler/cpp/cpp_helpers.h> 47#include <google/protobuf/stubs/strutil.h> 48#include <google/protobuf/io/printer.h> 49#include <google/protobuf/io/coded_stream.h> 50#include <google/protobuf/wire_format.h> 51#include <google/protobuf/descriptor.pb.h> 52 53 54namespace google { 55namespace protobuf { 56namespace compiler { 57namespace cpp { 58 59using internal::WireFormat; 60using internal::WireFormatLite; 61 62namespace { 63 64void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { 65 // Print the field's proto-syntax definition as a comment. We don't want to 66 // print group bodies so we cut off after the first line. 67 string def = field->DebugString(); 68 printer->Print("// $def$\n", 69 "def", def.substr(0, def.find_first_of('\n'))); 70} 71 72struct FieldOrderingByNumber { 73 inline bool operator()(const FieldDescriptor* a, 74 const FieldDescriptor* b) const { 75 return a->number() < b->number(); 76 } 77}; 78 79// Sort the fields of the given Descriptor by number into a new[]'d array 80// and return it. 81const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 82 const FieldDescriptor** fields = 83 new const FieldDescriptor*[descriptor->field_count()]; 84 for (int i = 0; i < descriptor->field_count(); i++) { 85 fields[i] = descriptor->field(i); 86 } 87 sort(fields, fields + descriptor->field_count(), 88 FieldOrderingByNumber()); 89 return fields; 90} 91 92// Functor for sorting extension ranges by their "start" field number. 93struct ExtensionRangeSorter { 94 bool operator()(const Descriptor::ExtensionRange* left, 95 const Descriptor::ExtensionRange* right) const { 96 return left->start < right->start; 97 } 98}; 99 100// Returns true if the "required" restriction check should be ignored for the 101// given field. 102inline static bool ShouldIgnoreRequiredFieldCheck( 103 const FieldDescriptor* field) { 104 return false; 105} 106 107// Returns true if the message type has any required fields. If it doesn't, 108// we can optimize out calls to its IsInitialized() method. 109// 110// already_seen is used to avoid checking the same type multiple times 111// (and also to protect against recursion). 112static bool HasRequiredFields( 113 const Descriptor* type, 114 hash_set<const Descriptor*>* already_seen) { 115 if (already_seen->count(type) > 0) { 116 // Since the first occurrence of a required field causes the whole 117 // function to return true, we can assume that if the type is already 118 // in the cache it didn't have any required fields. 119 return false; 120 } 121 already_seen->insert(type); 122 123 // If the type has extensions, an extension with message type could contain 124 // required fields, so we have to be conservative and assume such an 125 // extension exists. 126 if (type->extension_range_count() > 0) return true; 127 128 for (int i = 0; i < type->field_count(); i++) { 129 const FieldDescriptor* field = type->field(i); 130 if (field->is_required()) { 131 return true; 132 } 133 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 134 !ShouldIgnoreRequiredFieldCheck(field)) { 135 if (HasRequiredFields(field->message_type(), already_seen)) { 136 return true; 137 } 138 } 139 } 140 141 return false; 142} 143 144static bool HasRequiredFields(const Descriptor* type) { 145 hash_set<const Descriptor*> already_seen; 146 return HasRequiredFields(type, &already_seen); 147} 148 149// This returns an estimate of the compiler's alignment for the field. This 150// can't guarantee to be correct because the generated code could be compiled on 151// different systems with different alignment rules. The estimates below assume 152// 64-bit pointers. 153int EstimateAlignmentSize(const FieldDescriptor* field) { 154 if (field == NULL) return 0; 155 if (field->is_repeated()) return 8; 156 switch (field->cpp_type()) { 157 case FieldDescriptor::CPPTYPE_BOOL: 158 return 1; 159 160 case FieldDescriptor::CPPTYPE_INT32: 161 case FieldDescriptor::CPPTYPE_UINT32: 162 case FieldDescriptor::CPPTYPE_ENUM: 163 case FieldDescriptor::CPPTYPE_FLOAT: 164 return 4; 165 166 case FieldDescriptor::CPPTYPE_INT64: 167 case FieldDescriptor::CPPTYPE_UINT64: 168 case FieldDescriptor::CPPTYPE_DOUBLE: 169 case FieldDescriptor::CPPTYPE_STRING: 170 case FieldDescriptor::CPPTYPE_MESSAGE: 171 return 8; 172 } 173 GOOGLE_LOG(FATAL) << "Can't get here."; 174 return -1; // Make compiler happy. 175} 176 177// FieldGroup is just a helper for OptimizePadding below. It holds a vector of 178// fields that are grouped together because they have compatible alignment, and 179// a preferred location in the final field ordering. 180class FieldGroup { 181 public: 182 FieldGroup() 183 : preferred_location_(0) {} 184 185 // A group with a single field. 186 FieldGroup(float preferred_location, const FieldDescriptor* field) 187 : preferred_location_(preferred_location), 188 fields_(1, field) {} 189 190 // Append the fields in 'other' to this group. 191 void Append(const FieldGroup& other) { 192 if (other.fields_.empty()) { 193 return; 194 } 195 // Preferred location is the average among all the fields, so we weight by 196 // the number of fields on each FieldGroup object. 197 preferred_location_ = 198 (preferred_location_ * fields_.size() + 199 (other.preferred_location_ * other.fields_.size())) / 200 (fields_.size() + other.fields_.size()); 201 fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); 202 } 203 204 void SetPreferredLocation(float location) { preferred_location_ = location; } 205 const vector<const FieldDescriptor*>& fields() const { return fields_; } 206 207 // FieldGroup objects sort by their preferred location. 208 bool operator<(const FieldGroup& other) const { 209 return preferred_location_ < other.preferred_location_; 210 } 211 212 private: 213 // "preferred_location_" is an estimate of where this group should go in the 214 // final list of fields. We compute this by taking the average index of each 215 // field in this group in the original ordering of fields. This is very 216 // approximate, but should put this group close to where its member fields 217 // originally went. 218 float preferred_location_; 219 vector<const FieldDescriptor*> fields_; 220 // We rely on the default copy constructor and operator= so this type can be 221 // used in a vector. 222}; 223 224// Reorder 'fields' so that if the fields are output into a c++ class in the new 225// order, the alignment padding is minimized. We try to do this while keeping 226// each field as close as possible to its original position so that we don't 227// reduce cache locality much for function that access each field in order. 228void OptimizePadding(vector<const FieldDescriptor*>* fields) { 229 // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. 230 vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8; 231 for (int i = 0; i < fields->size(); ++i) { 232 switch (EstimateAlignmentSize((*fields)[i])) { 233 case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break; 234 case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break; 235 case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break; 236 default: 237 GOOGLE_LOG(FATAL) << "Unknown alignment size."; 238 } 239 } 240 241 // Now group fields aligned to 1 byte into sets of 4, and treat those like a 242 // single field aligned to 4 bytes. 243 for (int i = 0; i < aligned_to_1.size(); i += 4) { 244 FieldGroup field_group; 245 for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) { 246 field_group.Append(aligned_to_1[j]); 247 } 248 aligned_to_4.push_back(field_group); 249 } 250 // Sort by preferred location to keep fields as close to their original 251 // location as possible. Using stable_sort ensures that the output is 252 // consistent across runs. 253 stable_sort(aligned_to_4.begin(), aligned_to_4.end()); 254 255 // Now group fields aligned to 4 bytes (or the 4-field groups created above) 256 // into pairs, and treat those like a single field aligned to 8 bytes. 257 for (int i = 0; i < aligned_to_4.size(); i += 2) { 258 FieldGroup field_group; 259 for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) { 260 field_group.Append(aligned_to_4[j]); 261 } 262 if (i == aligned_to_4.size() - 1) { 263 // Move incomplete 4-byte block to the end. 264 field_group.SetPreferredLocation(fields->size() + 1); 265 } 266 aligned_to_8.push_back(field_group); 267 } 268 // Sort by preferred location. 269 stable_sort(aligned_to_8.begin(), aligned_to_8.end()); 270 271 // Now pull out all the FieldDescriptors in order. 272 fields->clear(); 273 for (int i = 0; i < aligned_to_8.size(); ++i) { 274 fields->insert(fields->end(), 275 aligned_to_8[i].fields().begin(), 276 aligned_to_8[i].fields().end()); 277 } 278} 279 280string MessageTypeProtoName(const FieldDescriptor* field) { 281 return field->message_type()->full_name(); 282} 283 284} 285 286// =================================================================== 287 288MessageGenerator::MessageGenerator(const Descriptor* descriptor, 289 const Options& options) 290 : descriptor_(descriptor), 291 classname_(ClassName(descriptor, false)), 292 options_(options), 293 field_generators_(descriptor, options), 294 nested_generators_(new scoped_ptr< 295 MessageGenerator>[descriptor->nested_type_count()]), 296 enum_generators_( 297 new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]), 298 extension_generators_(new scoped_ptr< 299 ExtensionGenerator>[descriptor->extension_count()]) { 300 301 for (int i = 0; i < descriptor->nested_type_count(); i++) { 302 nested_generators_[i].reset( 303 new MessageGenerator(descriptor->nested_type(i), options)); 304 } 305 306 for (int i = 0; i < descriptor->enum_type_count(); i++) { 307 enum_generators_[i].reset( 308 new EnumGenerator(descriptor->enum_type(i), options)); 309 } 310 311 for (int i = 0; i < descriptor->extension_count(); i++) { 312 extension_generators_[i].reset( 313 new ExtensionGenerator(descriptor->extension(i), options)); 314 } 315} 316 317MessageGenerator::~MessageGenerator() {} 318 319void MessageGenerator:: 320GenerateForwardDeclaration(io::Printer* printer) { 321 printer->Print("class $classname$;\n", 322 "classname", classname_); 323 324 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 325 nested_generators_[i]->GenerateForwardDeclaration(printer); 326 } 327} 328 329void MessageGenerator:: 330GenerateEnumDefinitions(io::Printer* printer) { 331 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 332 nested_generators_[i]->GenerateEnumDefinitions(printer); 333 } 334 335 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 336 enum_generators_[i]->GenerateDefinition(printer); 337 } 338} 339 340void MessageGenerator:: 341GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { 342 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 343 nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 344 } 345 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 346 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 347 } 348} 349 350void MessageGenerator:: 351GenerateFieldAccessorDeclarations(io::Printer* printer) { 352 for (int i = 0; i < descriptor_->field_count(); i++) { 353 const FieldDescriptor* field = descriptor_->field(i); 354 355 PrintFieldComment(printer, field); 356 357 map<string, string> vars; 358 SetCommonFieldVariables(field, &vars, options_); 359 vars["constant_name"] = FieldConstantName(field); 360 361 if (field->is_repeated()) { 362 printer->Print(vars, "inline int $name$_size() const$deprecation$;\n"); 363 } else { 364 printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n"); 365 } 366 367 printer->Print(vars, "inline void clear_$name$()$deprecation$;\n"); 368 printer->Print(vars, "static const int $constant_name$ = $number$;\n"); 369 370 // Generate type-specific accessor declarations. 371 field_generators_.get(field).GenerateAccessorDeclarations(printer); 372 373 printer->Print("\n"); 374 } 375 376 if (descriptor_->extension_range_count() > 0) { 377 // Generate accessors for extensions. We just call a macro located in 378 // extension_set.h since the accessors about 80 lines of static code. 379 printer->Print( 380 "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n", 381 "classname", classname_); 382 } 383 384 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 385 printer->Print( 386 "inline $camel_oneof_name$Case $oneof_name$_case() const;\n", 387 "camel_oneof_name", 388 UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true), 389 "oneof_name", descriptor_->oneof_decl(i)->name()); 390 } 391} 392 393void MessageGenerator:: 394GenerateFieldAccessorDefinitions(io::Printer* printer) { 395 printer->Print("// $classname$\n\n", "classname", classname_); 396 397 for (int i = 0; i < descriptor_->field_count(); i++) { 398 const FieldDescriptor* field = descriptor_->field(i); 399 400 PrintFieldComment(printer, field); 401 402 map<string, string> vars; 403 SetCommonFieldVariables(field, &vars, options_); 404 405 // Generate has_$name$() or $name$_size(). 406 if (field->is_repeated()) { 407 printer->Print(vars, 408 "inline int $classname$::$name$_size() const {\n" 409 " return $name$_.size();\n" 410 "}\n"); 411 } else if (field->containing_oneof()) { 412 // Singular field in a oneof 413 vars["field_name"] = UnderscoresToCamelCase(field->name(), true); 414 vars["oneof_name"] = field->containing_oneof()->name(); 415 vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); 416 printer->Print(vars, 417 "inline bool $classname$::has_$name$() const {\n" 418 " return $oneof_name$_case() == k$field_name$;\n" 419 "}\n" 420 "inline void $classname$::set_has_$name$() {\n" 421 " _oneof_case_[$oneof_index$] = k$field_name$;\n" 422 "}\n"); 423 } else { 424 // Singular field. 425 char buffer[kFastToBufferSize]; 426 vars["has_array_index"] = SimpleItoa(field->index() / 32); 427 vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); 428 printer->Print(vars, 429 "inline bool $classname$::has_$name$() const {\n" 430 " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" 431 "}\n" 432 "inline void $classname$::set_has_$name$() {\n" 433 " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" 434 "}\n" 435 "inline void $classname$::clear_has_$name$() {\n" 436 " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" 437 "}\n" 438 ); 439 } 440 441 // Generate clear_$name$() 442 printer->Print(vars, 443 "inline void $classname$::clear_$name$() {\n"); 444 445 printer->Indent(); 446 447 if (field->containing_oneof()) { 448 // Clear this field only if it is the active field in this oneof, 449 // otherwise ignore 450 printer->Print(vars, 451 "if (has_$name$()) {\n"); 452 printer->Indent(); 453 field_generators_.get(field).GenerateClearingCode(printer); 454 printer->Print(vars, 455 "clear_has_$oneof_name$();\n"); 456 printer->Outdent(); 457 printer->Print("}\n"); 458 } else { 459 field_generators_.get(field).GenerateClearingCode(printer); 460 if (!field->is_repeated()) { 461 printer->Print(vars, 462 "clear_has_$name$();\n"); 463 } 464 } 465 466 printer->Outdent(); 467 printer->Print("}\n"); 468 469 // Generate type-specific accessors. 470 field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); 471 472 printer->Print("\n"); 473 } 474 475 // Generate has_$name$() and clear_has_$name$() functions for oneofs 476 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 477 map<string, string> vars; 478 vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); 479 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); 480 vars["cap_oneof_name"] = 481 ToUpper(descriptor_->oneof_decl(i)->name()); 482 vars["classname"] = classname_; 483 printer->Print( 484 vars, 485 "inline bool $classname$::has_$oneof_name$() {\n" 486 " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" 487 "}\n" 488 "inline void $classname$::clear_has_$oneof_name$() {\n" 489 " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" 490 "}\n"); 491 } 492} 493 494// Helper for the code that emits the Clear() method. 495static bool CanClearByZeroing(const FieldDescriptor* field) { 496 if (field->is_repeated() || field->is_extension()) return false; 497 switch (field->cpp_type()) { 498 case internal::WireFormatLite::CPPTYPE_ENUM: 499 return field->default_value_enum()->number() == 0; 500 case internal::WireFormatLite::CPPTYPE_INT32: 501 return field->default_value_int32() == 0; 502 case internal::WireFormatLite::CPPTYPE_INT64: 503 return field->default_value_int64() == 0; 504 case internal::WireFormatLite::CPPTYPE_UINT32: 505 return field->default_value_uint32() == 0; 506 case internal::WireFormatLite::CPPTYPE_UINT64: 507 return field->default_value_uint64() == 0; 508 case internal::WireFormatLite::CPPTYPE_FLOAT: 509 return field->default_value_float() == 0; 510 case internal::WireFormatLite::CPPTYPE_DOUBLE: 511 return field->default_value_double() == 0; 512 case internal::WireFormatLite::CPPTYPE_BOOL: 513 return field->default_value_bool() == false; 514 default: 515 return false; 516 } 517} 518 519void MessageGenerator:: 520GenerateClassDefinition(io::Printer* printer) { 521 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 522 nested_generators_[i]->GenerateClassDefinition(printer); 523 printer->Print("\n"); 524 printer->Print(kThinSeparator); 525 printer->Print("\n"); 526 } 527 528 map<string, string> vars; 529 vars["classname"] = classname_; 530 vars["field_count"] = SimpleItoa(descriptor_->field_count()); 531 vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count()); 532 if (options_.dllexport_decl.empty()) { 533 vars["dllexport"] = ""; 534 } else { 535 vars["dllexport"] = options_.dllexport_decl + " "; 536 } 537 vars["superclass"] = SuperClassName(descriptor_); 538 539 printer->Print(vars, 540 "class $dllexport$$classname$ : public $superclass$ {\n" 541 " public:\n"); 542 printer->Indent(); 543 544 printer->Print(vars, 545 "$classname$();\n" 546 "virtual ~$classname$();\n" 547 "\n" 548 "$classname$(const $classname$& from);\n" 549 "\n" 550 "inline $classname$& operator=(const $classname$& from) {\n" 551 " CopyFrom(from);\n" 552 " return *this;\n" 553 "}\n" 554 "\n"); 555 556 if (UseUnknownFieldSet(descriptor_->file())) { 557 printer->Print( 558 "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n" 559 " return _unknown_fields_;\n" 560 "}\n" 561 "\n" 562 "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n" 563 " return &_unknown_fields_;\n" 564 "}\n" 565 "\n"); 566 } else { 567 printer->Print( 568 "inline const ::std::string& unknown_fields() const {\n" 569 " return _unknown_fields_;\n" 570 "}\n" 571 "\n" 572 "inline ::std::string* mutable_unknown_fields() {\n" 573 " return &_unknown_fields_;\n" 574 "}\n" 575 "\n"); 576 } 577 578 // Only generate this member if it's not disabled. 579 if (HasDescriptorMethods(descriptor_->file()) && 580 !descriptor_->options().no_standard_descriptor_accessor()) { 581 printer->Print(vars, 582 "static const ::google::protobuf::Descriptor* descriptor();\n"); 583 } 584 585 printer->Print(vars, 586 "static const $classname$& default_instance();\n" 587 "\n"); 588 589 // Generate enum values for every field in oneofs. One list is generated for 590 // each oneof with an additional *_NOT_SET value. 591 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 592 printer->Print( 593 "enum $camel_oneof_name$Case {\n", 594 "camel_oneof_name", 595 UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); 596 printer->Indent(); 597 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 598 printer->Print( 599 "k$field_name$ = $field_number$,\n", 600 "field_name", 601 UnderscoresToCamelCase( 602 descriptor_->oneof_decl(i)->field(j)->name(), true), 603 "field_number", 604 SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number())); 605 } 606 printer->Print( 607 "$cap_oneof_name$_NOT_SET = 0,\n", 608 "cap_oneof_name", 609 ToUpper(descriptor_->oneof_decl(i)->name())); 610 printer->Outdent(); 611 printer->Print( 612 "};\n" 613 "\n"); 614 } 615 616 if (!StaticInitializersForced(descriptor_->file())) { 617 printer->Print(vars, 618 "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" 619 "// Returns the internal default instance pointer. This function can\n" 620 "// return NULL thus should not be used by the user. This is intended\n" 621 "// for Protobuf internal code. Please use default_instance() declared\n" 622 "// above instead.\n" 623 "static inline const $classname$* internal_default_instance() {\n" 624 " return default_instance_;\n" 625 "}\n" 626 "#endif\n" 627 "\n"); 628 } 629 630 631 printer->Print(vars, 632 "void Swap($classname$* other);\n" 633 "\n" 634 "// implements Message ----------------------------------------------\n" 635 "\n" 636 "$classname$* New() const;\n"); 637 638 if (HasGeneratedMethods(descriptor_->file())) { 639 if (HasDescriptorMethods(descriptor_->file())) { 640 printer->Print(vars, 641 "void CopyFrom(const ::google::protobuf::Message& from);\n" 642 "void MergeFrom(const ::google::protobuf::Message& from);\n"); 643 } else { 644 printer->Print(vars, 645 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n"); 646 } 647 648 printer->Print(vars, 649 "void CopyFrom(const $classname$& from);\n" 650 "void MergeFrom(const $classname$& from);\n" 651 "void Clear();\n" 652 "bool IsInitialized() const;\n" 653 "\n" 654 "int ByteSize() const;\n" 655 "bool MergePartialFromCodedStream(\n" 656 " ::google::protobuf::io::CodedInputStream* input);\n" 657 "void SerializeWithCachedSizes(\n" 658 " ::google::protobuf::io::CodedOutputStream* output) const;\n"); 659 // DiscardUnknownFields() is implemented in message.cc using reflections. We 660 // need to implement this function in generated code for messages. 661 if (!UseUnknownFieldSet(descriptor_->file())) { 662 printer->Print( 663 "void DiscardUnknownFields();\n"); 664 } 665 if (HasFastArraySerialization(descriptor_->file())) { 666 printer->Print( 667 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n"); 668 } 669 } 670 671 // Check all FieldDescriptors including those in oneofs to estimate 672 // whether ::std::string is likely to be used, and depending on that 673 // estimate, set uses_string_ to true or false. That contols 674 // whether to force initialization of empty_string_ in SharedCtor(). 675 // It's often advantageous to do so to keep "is empty_string_ 676 // inited?" code from appearing all over the place. 677 vector<const FieldDescriptor*> descriptors; 678 for (int i = 0; i < descriptor_->field_count(); i++) { 679 descriptors.push_back(descriptor_->field(i)); 680 } 681 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 682 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 683 descriptors.push_back(descriptor_->oneof_decl(i)->field(j)); 684 } 685 } 686 uses_string_ = false; 687 for (int i = 0; i < descriptors.size(); i++) { 688 const FieldDescriptor* field = descriptors[i]; 689 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { 690 switch (field->options().ctype()) { 691 default: uses_string_ = true; break; 692 } 693 } 694 } 695 696 printer->Print( 697 "int GetCachedSize() const { return _cached_size_; }\n" 698 "private:\n" 699 "void SharedCtor();\n" 700 "void SharedDtor();\n" 701 "void SetCachedSize(int size) const;\n" 702 "public:\n"); 703 704 if (HasDescriptorMethods(descriptor_->file())) { 705 printer->Print( 706 "::google::protobuf::Metadata GetMetadata() const;\n" 707 "\n"); 708 } else { 709 printer->Print( 710 "::std::string GetTypeName() const;\n" 711 "\n"); 712 } 713 714 printer->Print( 715 "// nested types ----------------------------------------------------\n" 716 "\n"); 717 718 // Import all nested message classes into this class's scope with typedefs. 719 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 720 const Descriptor* nested_type = descriptor_->nested_type(i); 721 printer->Print("typedef $nested_full_name$ $nested_name$;\n", 722 "nested_name", nested_type->name(), 723 "nested_full_name", ClassName(nested_type, false)); 724 } 725 726 if (descriptor_->nested_type_count() > 0) { 727 printer->Print("\n"); 728 } 729 730 // Import all nested enums and their values into this class's scope with 731 // typedefs and constants. 732 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 733 enum_generators_[i]->GenerateSymbolImports(printer); 734 printer->Print("\n"); 735 } 736 737 printer->Print( 738 "// accessors -------------------------------------------------------\n" 739 "\n"); 740 741 // Generate accessor methods for all fields. 742 GenerateFieldAccessorDeclarations(printer); 743 744 // Declare extension identifiers. 745 for (int i = 0; i < descriptor_->extension_count(); i++) { 746 extension_generators_[i]->GenerateDeclaration(printer); 747 } 748 749 750 printer->Print( 751 "// @@protoc_insertion_point(class_scope:$full_name$)\n", 752 "full_name", descriptor_->full_name()); 753 754 // Generate private members. 755 printer->Outdent(); 756 printer->Print(" private:\n"); 757 printer->Indent(); 758 759 760 for (int i = 0; i < descriptor_->field_count(); i++) { 761 if (!descriptor_->field(i)->is_repeated()) { 762 printer->Print( 763 "inline void set_has_$name$();\n", 764 "name", FieldName(descriptor_->field(i))); 765 if (!descriptor_->field(i)->containing_oneof()) { 766 printer->Print( 767 "inline void clear_has_$name$();\n", 768 "name", FieldName(descriptor_->field(i))); 769 } 770 } 771 } 772 printer->Print("\n"); 773 774 // Generate oneof function declarations 775 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 776 printer->Print( 777 "inline bool has_$oneof_name$();\n" 778 "void clear_$oneof_name$();\n" 779 "inline void clear_has_$oneof_name$();\n\n", 780 "oneof_name", descriptor_->oneof_decl(i)->name()); 781 } 782 783 // Prepare decls for _cached_size_ and _has_bits_. Their position in the 784 // output will be determined later. 785 786 bool need_to_emit_cached_size = true; 787 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. 788 const string cached_size_decl = "mutable int _cached_size_;\n"; 789 790 // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields. 791 size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4; 792 if (descriptor_->field_count() == 0) { 793 // Zero-size arrays aren't technically allowed, and MSVC in particular 794 // doesn't like them. We still need to declare these arrays to make 795 // other code compile. Since this is an uncommon case, we'll just declare 796 // them with size 1 and waste some space. Oh well. 797 sizeof_has_bits = 4; 798 } 799 const string has_bits_decl = sizeof_has_bits == 0 ? "" : 800 "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n"; 801 802 803 // To minimize padding, data members are divided into three sections: 804 // (1) members assumed to align to 8 bytes 805 // (2) members corresponding to message fields, re-ordered to optimize 806 // alignment. 807 // (3) members assumed to align to 4 bytes. 808 809 // Members assumed to align to 8 bytes: 810 811 if (descriptor_->extension_range_count() > 0) { 812 printer->Print( 813 "::google::protobuf::internal::ExtensionSet _extensions_;\n" 814 "\n"); 815 } 816 817 if (UseUnknownFieldSet(descriptor_->file())) { 818 printer->Print( 819 "::google::protobuf::UnknownFieldSet _unknown_fields_;\n" 820 "\n"); 821 } else { 822 printer->Print( 823 "::std::string _unknown_fields_;\n" 824 "\n"); 825 } 826 827 // _has_bits_ is frequently accessed, so to reduce code size and improve 828 // speed, it should be close to the start of the object. But, try not to 829 // waste space:_has_bits_ by itself always makes sense if its size is a 830 // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together 831 // will work well. 832 printer->Print(has_bits_decl.c_str()); 833 if ((sizeof_has_bits % 8) != 0) { 834 printer->Print(cached_size_decl.c_str()); 835 need_to_emit_cached_size = false; 836 } 837 838 // Field members: 839 840 // List fields which doesn't belong to any oneof 841 vector<const FieldDescriptor*> fields; 842 hash_map<string, int> fieldname_to_chunk; 843 for (int i = 0; i < descriptor_->field_count(); i++) { 844 if (!descriptor_->field(i)->containing_oneof()) { 845 const FieldDescriptor* field = descriptor_->field(i); 846 fields.push_back(field); 847 fieldname_to_chunk[FieldName(field)] = i / 8; 848 } 849 } 850 OptimizePadding(&fields); 851 // Emit some private and static members 852 runs_of_fields_ = vector< vector<string> >(1); 853 for (int i = 0; i < fields.size(); ++i) { 854 const FieldDescriptor* field = fields[i]; 855 const FieldGenerator& generator = field_generators_.get(field); 856 generator.GenerateStaticMembers(printer); 857 generator.GeneratePrivateMembers(printer); 858 if (CanClearByZeroing(field)) { 859 const string& fieldname = FieldName(field); 860 if (!runs_of_fields_.back().empty() && 861 (fieldname_to_chunk[runs_of_fields_.back().back()] != 862 fieldname_to_chunk[fieldname])) { 863 runs_of_fields_.push_back(vector<string>()); 864 } 865 runs_of_fields_.back().push_back(fieldname); 866 } else if (!runs_of_fields_.back().empty()) { 867 runs_of_fields_.push_back(vector<string>()); 868 } 869 } 870 871 // For each oneof generate a union 872 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 873 printer->Print( 874 "union $camel_oneof_name$Union {\n", 875 "camel_oneof_name", 876 UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); 877 printer->Indent(); 878 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 879 field_generators_.get(descriptor_->oneof_decl(i)-> 880 field(j)).GeneratePrivateMembers(printer); 881 } 882 printer->Outdent(); 883 printer->Print( 884 "} $oneof_name$_;\n", 885 "oneof_name", descriptor_->oneof_decl(i)->name()); 886 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 887 field_generators_.get(descriptor_->oneof_decl(i)-> 888 field(j)).GenerateStaticMembers(printer); 889 } 890 } 891 892 // Members assumed to align to 4 bytes: 893 894 if (need_to_emit_cached_size) { 895 printer->Print(cached_size_decl.c_str()); 896 need_to_emit_cached_size = false; 897 } 898 899 // Generate _oneof_case_. 900 if (descriptor_->oneof_decl_count() > 0) { 901 printer->Print(vars, 902 "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n" 903 "\n"); 904 } 905 906 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as 907 // friends so that they can access private static variables like 908 // default_instance_ and reflection_. 909 PrintHandlingOptionalStaticInitializers( 910 descriptor_->file(), printer, 911 // With static initializers. 912 "friend void $dllexport_decl$ $adddescriptorsname$();\n", 913 // Without. 914 "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n", 915 // Vars. 916 "dllexport_decl", options_.dllexport_decl, 917 "adddescriptorsname", 918 GlobalAddDescriptorsName(descriptor_->file()->name())); 919 920 printer->Print( 921 "friend void $assigndescriptorsname$();\n" 922 "friend void $shutdownfilename$();\n" 923 "\n", 924 "assigndescriptorsname", 925 GlobalAssignDescriptorsName(descriptor_->file()->name()), 926 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); 927 928 printer->Print( 929 "void InitAsDefaultInstance();\n" 930 "static $classname$* default_instance_;\n", 931 "classname", classname_); 932 933 printer->Outdent(); 934 printer->Print(vars, "};"); 935 GOOGLE_DCHECK(!need_to_emit_cached_size); 936} 937 938void MessageGenerator:: 939GenerateInlineMethods(io::Printer* printer) { 940 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 941 nested_generators_[i]->GenerateInlineMethods(printer); 942 printer->Print(kThinSeparator); 943 printer->Print("\n"); 944 } 945 946 GenerateFieldAccessorDefinitions(printer); 947 948 // Generate oneof_case() functions. 949 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 950 map<string, string> vars; 951 vars["class_name"] = classname_; 952 vars["camel_oneof_name"] = UnderscoresToCamelCase( 953 descriptor_->oneof_decl(i)->name(), true); 954 vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); 955 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); 956 printer->Print( 957 vars, 958 "inline $class_name$::$camel_oneof_name$Case $class_name$::" 959 "$oneof_name$_case() const {\n" 960 " return $class_name$::$camel_oneof_name$Case(" 961 "_oneof_case_[$oneof_index$]);\n" 962 "}\n"); 963 } 964} 965 966void MessageGenerator:: 967GenerateDescriptorDeclarations(io::Printer* printer) { 968 printer->Print( 969 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n" 970 "const ::google::protobuf::internal::GeneratedMessageReflection*\n" 971 " $name$_reflection_ = NULL;\n", 972 "name", classname_); 973 974 // Generate oneof default instance for reflection usage. 975 if (descriptor_->oneof_decl_count() > 0) { 976 printer->Print("struct $name$OneofInstance {\n", 977 "name", classname_); 978 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 979 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 980 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 981 printer->Print(" "); 982 if (IsStringOrMessage(field)) { 983 printer->Print("const "); 984 } 985 field_generators_.get(field).GeneratePrivateMembers(printer); 986 } 987 } 988 989 printer->Print("}* $name$_default_oneof_instance_ = NULL;\n", 990 "name", classname_); 991 } 992 993 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 994 nested_generators_[i]->GenerateDescriptorDeclarations(printer); 995 } 996 997 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 998 printer->Print( 999 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", 1000 "name", ClassName(descriptor_->enum_type(i), false)); 1001 } 1002} 1003 1004void MessageGenerator:: 1005GenerateDescriptorInitializer(io::Printer* printer, int index) { 1006 // TODO(kenton): Passing the index to this method is redundant; just use 1007 // descriptor_->index() instead. 1008 map<string, string> vars; 1009 vars["classname"] = classname_; 1010 vars["index"] = SimpleItoa(index); 1011 1012 // Obtain the descriptor from the parent's descriptor. 1013 if (descriptor_->containing_type() == NULL) { 1014 printer->Print(vars, 1015 "$classname$_descriptor_ = file->message_type($index$);\n"); 1016 } else { 1017 vars["parent"] = ClassName(descriptor_->containing_type(), false); 1018 printer->Print(vars, 1019 "$classname$_descriptor_ = " 1020 "$parent$_descriptor_->nested_type($index$);\n"); 1021 } 1022 1023 // Generate the offsets. 1024 GenerateOffsets(printer); 1025 1026 // Construct the reflection object. 1027 printer->Print(vars, 1028 "$classname$_reflection_ =\n" 1029 " new ::google::protobuf::internal::GeneratedMessageReflection(\n" 1030 " $classname$_descriptor_,\n" 1031 " $classname$::default_instance_,\n" 1032 " $classname$_offsets_,\n" 1033 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n" 1034 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 1035 "$classname$, _unknown_fields_),\n"); 1036 if (descriptor_->extension_range_count() > 0) { 1037 printer->Print(vars, 1038 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 1039 "$classname$, _extensions_),\n"); 1040 } else { 1041 // No extensions. 1042 printer->Print(vars, 1043 " -1,\n"); 1044 } 1045 1046 if (descriptor_->oneof_decl_count() > 0) { 1047 printer->Print(vars, 1048 " $classname$_default_oneof_instance_,\n" 1049 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 1050 "$classname$, _oneof_case_[0]),\n"); 1051 } 1052 1053 printer->Print( 1054 " ::google::protobuf::DescriptorPool::generated_pool(),\n"); 1055 printer->Print(vars, 1056 " ::google::protobuf::MessageFactory::generated_factory(),\n"); 1057 printer->Print(vars, 1058 " sizeof($classname$));\n"); 1059 1060 // Handle nested types. 1061 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1062 nested_generators_[i]->GenerateDescriptorInitializer(printer, i); 1063 } 1064 1065 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 1066 enum_generators_[i]->GenerateDescriptorInitializer(printer, i); 1067 } 1068} 1069 1070void MessageGenerator:: 1071GenerateTypeRegistrations(io::Printer* printer) { 1072 // Register this message type with the message factory. 1073 printer->Print( 1074 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" 1075 " $classname$_descriptor_, &$classname$::default_instance());\n", 1076 "classname", classname_); 1077 1078 // Handle nested types. 1079 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1080 nested_generators_[i]->GenerateTypeRegistrations(printer); 1081 } 1082} 1083 1084void MessageGenerator:: 1085GenerateDefaultInstanceAllocator(io::Printer* printer) { 1086 // Construct the default instances of all fields, as they will be used 1087 // when creating the default instance of the entire message. 1088 for (int i = 0; i < descriptor_->field_count(); i++) { 1089 field_generators_.get(descriptor_->field(i)) 1090 .GenerateDefaultInstanceAllocator(printer); 1091 } 1092 1093 // Construct the default instance. We can't call InitAsDefaultInstance() yet 1094 // because we need to make sure all default instances that this one might 1095 // depend on are constructed first. 1096 printer->Print( 1097 "$classname$::default_instance_ = new $classname$();\n", 1098 "classname", classname_); 1099 1100 if ((descriptor_->oneof_decl_count() > 0) && 1101 HasDescriptorMethods(descriptor_->file())) { 1102 printer->Print( 1103 "$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n", 1104 "classname", classname_); 1105 } 1106 1107 // Handle nested types. 1108 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1109 nested_generators_[i]->GenerateDefaultInstanceAllocator(printer); 1110 } 1111 1112} 1113 1114void MessageGenerator:: 1115GenerateDefaultInstanceInitializer(io::Printer* printer) { 1116 printer->Print( 1117 "$classname$::default_instance_->InitAsDefaultInstance();\n", 1118 "classname", classname_); 1119 1120 // Register extensions. 1121 for (int i = 0; i < descriptor_->extension_count(); i++) { 1122 extension_generators_[i]->GenerateRegistration(printer); 1123 } 1124 1125 // Handle nested types. 1126 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1127 nested_generators_[i]->GenerateDefaultInstanceInitializer(printer); 1128 } 1129} 1130 1131void MessageGenerator:: 1132GenerateShutdownCode(io::Printer* printer) { 1133 printer->Print( 1134 "delete $classname$::default_instance_;\n", 1135 "classname", classname_); 1136 1137 if (HasDescriptorMethods(descriptor_->file())) { 1138 if (descriptor_->oneof_decl_count() > 0) { 1139 printer->Print( 1140 "delete $classname$_default_oneof_instance_;\n", 1141 "classname", classname_); 1142 } 1143 printer->Print( 1144 "delete $classname$_reflection_;\n", 1145 "classname", classname_); 1146 } 1147 1148 // Handle default instances of fields. 1149 for (int i = 0; i < descriptor_->field_count(); i++) { 1150 field_generators_.get(descriptor_->field(i)) 1151 .GenerateShutdownCode(printer); 1152 } 1153 1154 // Handle nested types. 1155 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1156 nested_generators_[i]->GenerateShutdownCode(printer); 1157 } 1158} 1159 1160void MessageGenerator:: 1161GenerateClassMethods(io::Printer* printer) { 1162 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 1163 enum_generators_[i]->GenerateMethods(printer); 1164 } 1165 1166 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1167 nested_generators_[i]->GenerateClassMethods(printer); 1168 printer->Print("\n"); 1169 printer->Print(kThinSeparator); 1170 printer->Print("\n"); 1171 } 1172 1173 // Generate non-inline field definitions. 1174 for (int i = 0; i < descriptor_->field_count(); i++) { 1175 field_generators_.get(descriptor_->field(i)) 1176 .GenerateNonInlineAccessorDefinitions(printer); 1177 } 1178 1179 // Generate field number constants. 1180 printer->Print("#ifndef _MSC_VER\n"); 1181 for (int i = 0; i < descriptor_->field_count(); i++) { 1182 const FieldDescriptor *field = descriptor_->field(i); 1183 printer->Print( 1184 "const int $classname$::$constant_name$;\n", 1185 "classname", ClassName(FieldScope(field), false), 1186 "constant_name", FieldConstantName(field)); 1187 } 1188 printer->Print( 1189 "#endif // !_MSC_VER\n" 1190 "\n"); 1191 1192 // Define extension identifiers. 1193 for (int i = 0; i < descriptor_->extension_count(); i++) { 1194 extension_generators_[i]->GenerateDefinition(printer); 1195 } 1196 1197 GenerateStructors(printer); 1198 printer->Print("\n"); 1199 1200 if (descriptor_->oneof_decl_count() > 0) { 1201 GenerateOneofClear(printer); 1202 printer->Print("\n"); 1203 } 1204 1205 if (HasGeneratedMethods(descriptor_->file())) { 1206 GenerateClear(printer); 1207 printer->Print("\n"); 1208 1209 GenerateMergeFromCodedStream(printer); 1210 printer->Print("\n"); 1211 1212 GenerateSerializeWithCachedSizes(printer); 1213 printer->Print("\n"); 1214 1215 if (HasFastArraySerialization(descriptor_->file())) { 1216 GenerateSerializeWithCachedSizesToArray(printer); 1217 printer->Print("\n"); 1218 } 1219 1220 GenerateByteSize(printer); 1221 printer->Print("\n"); 1222 1223 GenerateMergeFrom(printer); 1224 printer->Print("\n"); 1225 1226 GenerateCopyFrom(printer); 1227 printer->Print("\n"); 1228 1229 GenerateIsInitialized(printer); 1230 printer->Print("\n"); 1231 } 1232 1233 GenerateSwap(printer); 1234 printer->Print("\n"); 1235 1236 if (HasDescriptorMethods(descriptor_->file())) { 1237 printer->Print( 1238 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" 1239 " protobuf_AssignDescriptorsOnce();\n" 1240 " ::google::protobuf::Metadata metadata;\n" 1241 " metadata.descriptor = $classname$_descriptor_;\n" 1242 " metadata.reflection = $classname$_reflection_;\n" 1243 " return metadata;\n" 1244 "}\n" 1245 "\n", 1246 "classname", classname_); 1247 } else { 1248 printer->Print( 1249 "::std::string $classname$::GetTypeName() const {\n" 1250 " return \"$type_name$\";\n" 1251 "}\n" 1252 "\n", 1253 "classname", classname_, 1254 "type_name", descriptor_->full_name()); 1255 } 1256 1257} 1258 1259void MessageGenerator:: 1260GenerateOffsets(io::Printer* printer) { 1261 printer->Print( 1262 "static const int $classname$_offsets_[$field_count$] = {\n", 1263 "classname", classname_, 1264 "field_count", SimpleItoa(max( 1265 1, descriptor_->field_count() + descriptor_->oneof_decl_count()))); 1266 printer->Indent(); 1267 1268 for (int i = 0; i < descriptor_->field_count(); i++) { 1269 const FieldDescriptor* field = descriptor_->field(i); 1270 if (field->containing_oneof()) { 1271 printer->Print( 1272 "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(" 1273 "$classname$_default_oneof_instance_, $name$_),\n", 1274 "classname", classname_, 1275 "name", FieldName(field)); 1276 } else { 1277 printer->Print( 1278 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " 1279 "$name$_),\n", 1280 "classname", classname_, 1281 "name", FieldName(field)); 1282 } 1283 } 1284 1285 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1286 const OneofDescriptor* oneof = descriptor_->oneof_decl(i); 1287 printer->Print( 1288 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", 1289 "classname", classname_, 1290 "name", oneof->name()); 1291 } 1292 1293 printer->Outdent(); 1294 printer->Print("};\n"); 1295} 1296 1297void MessageGenerator:: 1298GenerateSharedConstructorCode(io::Printer* printer) { 1299 printer->Print( 1300 "void $classname$::SharedCtor() {\n", 1301 "classname", classname_); 1302 printer->Indent(); 1303 1304 printer->Print(StrCat( 1305 uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "", 1306 "_cached_size_ = 0;\n").c_str()); 1307 1308 for (int i = 0; i < descriptor_->field_count(); i++) { 1309 if (!descriptor_->field(i)->containing_oneof()) { 1310 field_generators_.get(descriptor_->field(i)) 1311 .GenerateConstructorCode(printer); 1312 } 1313 } 1314 1315 printer->Print( 1316 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); 1317 1318 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1319 printer->Print( 1320 "clear_has_$oneof_name$();\n", 1321 "oneof_name", descriptor_->oneof_decl(i)->name()); 1322 } 1323 1324 printer->Outdent(); 1325 printer->Print("}\n\n"); 1326} 1327 1328void MessageGenerator:: 1329GenerateSharedDestructorCode(io::Printer* printer) { 1330 printer->Print( 1331 "void $classname$::SharedDtor() {\n", 1332 "classname", classname_); 1333 printer->Indent(); 1334 // Write the destructors for each field except oneof members. 1335 for (int i = 0; i < descriptor_->field_count(); i++) { 1336 if (!descriptor_->field(i)->containing_oneof()) { 1337 field_generators_.get(descriptor_->field(i)) 1338 .GenerateDestructorCode(printer); 1339 } 1340 } 1341 1342 // Generate code to destruct oneofs. Clearing should do the work. 1343 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1344 printer->Print( 1345 "if (has_$oneof_name$()) {\n" 1346 " clear_$oneof_name$();\n" 1347 "}\n", 1348 "oneof_name", descriptor_->oneof_decl(i)->name()); 1349 } 1350 1351 PrintHandlingOptionalStaticInitializers( 1352 descriptor_->file(), printer, 1353 // With static initializers. 1354 "if (this != default_instance_) {\n", 1355 // Without. 1356 "if (this != &default_instance()) {\n"); 1357 1358 // We need to delete all embedded messages. 1359 // TODO(kenton): If we make unset messages point at default instances 1360 // instead of NULL, then it would make sense to move this code into 1361 // MessageFieldGenerator::GenerateDestructorCode(). 1362 for (int i = 0; i < descriptor_->field_count(); i++) { 1363 const FieldDescriptor* field = descriptor_->field(i); 1364 1365 if (!field->is_repeated() && 1366 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1367 // Skip oneof members 1368 if (!field->containing_oneof()) { 1369 printer->Print( 1370 " delete $name$_;\n", 1371 "name", FieldName(field)); 1372 } 1373 } 1374 } 1375 1376 printer->Outdent(); 1377 printer->Print( 1378 " }\n" 1379 "}\n" 1380 "\n"); 1381} 1382 1383void MessageGenerator:: 1384GenerateStructors(io::Printer* printer) { 1385 string superclass = SuperClassName(descriptor_); 1386 1387 // Generate the default constructor. 1388 printer->Print( 1389 "$classname$::$classname$()\n" 1390 " : $superclass$() {\n" 1391 " SharedCtor();\n" 1392 " // @@protoc_insertion_point(constructor:$full_name$)\n" 1393 "}\n", 1394 "classname", classname_, 1395 "superclass", superclass, 1396 "full_name", descriptor_->full_name()); 1397 1398 printer->Print( 1399 "\n" 1400 "void $classname$::InitAsDefaultInstance() {\n", 1401 "classname", classname_); 1402 1403 // The default instance needs all of its embedded message pointers 1404 // cross-linked to other default instances. We can't do this initialization 1405 // in the constructor because some other default instances may not have been 1406 // constructed yet at that time. 1407 // TODO(kenton): Maybe all message fields (even for non-default messages) 1408 // should be initialized to point at default instances rather than NULL? 1409 for (int i = 0; i < descriptor_->field_count(); i++) { 1410 const FieldDescriptor* field = descriptor_->field(i); 1411 1412 if (!field->is_repeated() && 1413 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 1414 (field->containing_oneof() == NULL || 1415 HasDescriptorMethods(descriptor_->file()))) { 1416 string name; 1417 if (field->containing_oneof()) { 1418 name = classname_ + "_default_oneof_instance_->"; 1419 } 1420 name += FieldName(field); 1421 PrintHandlingOptionalStaticInitializers( 1422 descriptor_->file(), printer, 1423 // With static initializers. 1424 " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", 1425 // Without. 1426 " $name$_ = const_cast< $type$*>(\n" 1427 " $type$::internal_default_instance());\n", 1428 // Vars. 1429 "name", name, 1430 "type", FieldMessageTypeName(field)); 1431 } else if (field->containing_oneof() && 1432 HasDescriptorMethods(descriptor_->file())) { 1433 field_generators_.get(descriptor_->field(i)) 1434 .GenerateConstructorCode(printer); 1435 } 1436 } 1437 printer->Print( 1438 "}\n" 1439 "\n"); 1440 1441 // Generate the copy constructor. 1442 printer->Print( 1443 "$classname$::$classname$(const $classname$& from)\n" 1444 " : $superclass$() {\n" 1445 " SharedCtor();\n" 1446 " MergeFrom(from);\n" 1447 " // @@protoc_insertion_point(copy_constructor:$full_name$)\n" 1448 "}\n" 1449 "\n", 1450 "classname", classname_, 1451 "superclass", superclass, 1452 "full_name", descriptor_->full_name()); 1453 1454 // Generate the shared constructor code. 1455 GenerateSharedConstructorCode(printer); 1456 1457 // Generate the destructor. 1458 printer->Print( 1459 "$classname$::~$classname$() {\n" 1460 " // @@protoc_insertion_point(destructor:$full_name$)\n" 1461 " SharedDtor();\n" 1462 "}\n" 1463 "\n", 1464 "classname", classname_, 1465 "full_name", descriptor_->full_name()); 1466 1467 // Generate the shared destructor code. 1468 GenerateSharedDestructorCode(printer); 1469 1470 // Generate SetCachedSize. 1471 printer->Print( 1472 "void $classname$::SetCachedSize(int size) const {\n" 1473 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 1474 " _cached_size_ = size;\n" 1475 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 1476 "}\n", 1477 "classname", classname_); 1478 1479 // Only generate this member if it's not disabled. 1480 if (HasDescriptorMethods(descriptor_->file()) && 1481 !descriptor_->options().no_standard_descriptor_accessor()) { 1482 printer->Print( 1483 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" 1484 " protobuf_AssignDescriptorsOnce();\n" 1485 " return $classname$_descriptor_;\n" 1486 "}\n" 1487 "\n", 1488 "classname", classname_, 1489 "adddescriptorsname", 1490 GlobalAddDescriptorsName(descriptor_->file()->name())); 1491 } 1492 1493 printer->Print( 1494 "const $classname$& $classname$::default_instance() {\n", 1495 "classname", classname_); 1496 1497 PrintHandlingOptionalStaticInitializers( 1498 descriptor_->file(), printer, 1499 // With static initializers. 1500 " if (default_instance_ == NULL) $adddescriptorsname$();\n", 1501 // Without. 1502 " $adddescriptorsname$();\n", 1503 // Vars. 1504 "adddescriptorsname", 1505 GlobalAddDescriptorsName(descriptor_->file()->name())); 1506 1507 printer->Print( 1508 " return *default_instance_;\n" 1509 "}\n" 1510 "\n" 1511 "$classname$* $classname$::default_instance_ = NULL;\n" 1512 "\n", 1513 "classname", classname_); 1514 1515 printer->Print( 1516 "$classname$* $classname$::New() const {\n" 1517 " return new $classname$;\n" 1518 "}\n", 1519 "classname", classname_); 1520 1521} 1522 1523// Return the number of bits set in n, a non-negative integer. 1524static int popcnt(uint32 n) { 1525 int result = 0; 1526 while (n != 0) { 1527 result += (n & 1); 1528 n = n / 2; 1529 } 1530 return result; 1531} 1532 1533void MessageGenerator:: 1534GenerateClear(io::Printer* printer) { 1535 printer->Print("void $classname$::Clear() {\n", 1536 "classname", classname_); 1537 printer->Indent(); 1538 1539 // Step 1: Extensions 1540 if (descriptor_->extension_range_count() > 0) { 1541 printer->Print("_extensions_.Clear();\n"); 1542 } 1543 1544 // Step 2: Everything but extensions, repeateds, unions. 1545 // These are handled in chunks of 8. The first chunk is 1546 // the non-extensions-non-repeateds-non-unions in 1547 // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7), 1548 // and the second chunk is the same for 1549 // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15), 1550 // etc. 1551 set<int> step2_indices; 1552 hash_map<string, int> fieldname_to_chunk; 1553 hash_map<int, string> memsets_for_chunk; 1554 hash_map<int, int> memset_field_count_for_chunk; 1555 hash_set<string> handled; // fields that appear anywhere in memsets_for_chunk 1556 hash_map<int, uint32> fields_mask_for_chunk; 1557 for (int i = 0; i < descriptor_->field_count(); i++) { 1558 const FieldDescriptor* field = descriptor_->field(i); 1559 if (!field->is_repeated() && !field->containing_oneof()) { 1560 step2_indices.insert(i); 1561 int chunk = i / 8; 1562 fieldname_to_chunk[FieldName(field)] = chunk; 1563 fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32); 1564 } 1565 } 1566 1567 // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0. 1568 // The generated code uses two macros to help it clear runs of fields: 1569 // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message. 1570 // ZR_ zeroes a non-empty range of fields via memset. 1571 const char* macros = 1572 "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \\\n" 1573 " &reinterpret_cast<$classname$*>(16)->f) - \\\n" 1574 " reinterpret_cast<char*>(16))\n\n" 1575 "#define ZR_(first, last) do { \\\n" 1576 " size_t f = OFFSET_OF_FIELD_(first); \\\n" 1577 " size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n" 1578 " ::memset(&first, 0, n); \\\n" 1579 " } while (0)\n\n"; 1580 for (int i = 0; i < runs_of_fields_.size(); i++) { 1581 const vector<string>& run = runs_of_fields_[i]; 1582 if (run.size() < 2) continue; 1583 const string& first_field_name = run[0]; 1584 const string& last_field_name = run.back(); 1585 int chunk = fieldname_to_chunk[run[0]]; 1586 memsets_for_chunk[chunk].append( 1587 "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n"); 1588 for (int j = 0; j < run.size(); j++) { 1589 GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]); 1590 handled.insert(run[j]); 1591 } 1592 memset_field_count_for_chunk[chunk] += run.size(); 1593 } 1594 const bool macros_are_needed = handled.size() > 0; 1595 if (macros_are_needed) { 1596 printer->Outdent(); 1597 printer->Print(macros, 1598 "classname", classname_); 1599 printer->Indent(); 1600 } 1601 // Step 2b: Finish step 2, ignoring fields handled in step 2a. 1602 int last_index = -1; 1603 bool chunk_block_in_progress = false; 1604 for (int i = 0; i < descriptor_->field_count(); i++) { 1605 if (step2_indices.count(i) == 0) continue; 1606 const FieldDescriptor* field = descriptor_->field(i); 1607 const string fieldname = FieldName(field); 1608 if (i / 8 != last_index / 8 || last_index < 0) { 1609 // End previous chunk, if there was one. 1610 if (chunk_block_in_progress) { 1611 printer->Outdent(); 1612 printer->Print("}\n"); 1613 chunk_block_in_progress = false; 1614 } 1615 // Start chunk. 1616 const string& memsets = memsets_for_chunk[i / 8]; 1617 uint32 mask = fields_mask_for_chunk[i / 8]; 1618 int count = popcnt(mask); 1619 if (count == 1 || 1620 (count <= 4 && count == memset_field_count_for_chunk[i / 8])) { 1621 // No "if" here because the chunk is trivial. 1622 } else { 1623 printer->Print( 1624 "if (_has_bits_[$index$ / 32] & $mask$) {\n", 1625 "index", SimpleItoa(i / 8 * 8), 1626 "mask", SimpleItoa(mask)); 1627 printer->Indent(); 1628 chunk_block_in_progress = true; 1629 } 1630 printer->Print(memsets.c_str()); 1631 } 1632 last_index = i; 1633 if (handled.count(fieldname) > 0) continue; 1634 1635 // It's faster to just overwrite primitive types, but we should 1636 // only clear strings and messages if they were set. 1637 // TODO(kenton): Let the CppFieldGenerator decide this somehow. 1638 bool should_check_bit = 1639 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 1640 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; 1641 1642 if (should_check_bit) { 1643 printer->Print("if (has_$name$()) {\n", "name", fieldname); 1644 printer->Indent(); 1645 } 1646 1647 field_generators_.get(field).GenerateClearingCode(printer); 1648 1649 if (should_check_bit) { 1650 printer->Outdent(); 1651 printer->Print("}\n"); 1652 } 1653 } 1654 1655 if (chunk_block_in_progress) { 1656 printer->Outdent(); 1657 printer->Print("}\n"); 1658 } 1659 if (macros_are_needed) { 1660 printer->Outdent(); 1661 printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n"); 1662 printer->Indent(); 1663 } 1664 1665 // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here. 1666 for (int i = 0; i < descriptor_->field_count(); i++) { 1667 const FieldDescriptor* field = descriptor_->field(i); 1668 1669 if (field->is_repeated()) { 1670 field_generators_.get(field).GenerateClearingCode(printer); 1671 } 1672 } 1673 1674 // Step 4: Unions. 1675 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1676 printer->Print( 1677 "clear_$oneof_name$();\n", 1678 "oneof_name", descriptor_->oneof_decl(i)->name()); 1679 } 1680 1681 // Step 5: Everything else. 1682 printer->Print( 1683 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); 1684 1685 if (UseUnknownFieldSet(descriptor_->file())) { 1686 printer->Print( 1687 "mutable_unknown_fields()->Clear();\n"); 1688 } else { 1689 printer->Print( 1690 "mutable_unknown_fields()->clear();\n"); 1691 } 1692 1693 printer->Outdent(); 1694 printer->Print("}\n"); 1695} 1696 1697void MessageGenerator:: 1698GenerateOneofClear(io::Printer* printer) { 1699 // Generated function clears the active field and union case (e.g. foo_case_). 1700 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1701 printer->Print( 1702 "void $classname$::clear_$oneofname$() {\n", 1703 "classname", classname_, 1704 "oneofname", descriptor_->oneof_decl(i)->name()); 1705 printer->Indent(); 1706 printer->Print( 1707 "switch($oneofname$_case()) {\n", 1708 "oneofname", descriptor_->oneof_decl(i)->name()); 1709 printer->Indent(); 1710 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 1711 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 1712 printer->Print( 1713 "case k$field_name$: {\n", 1714 "field_name", UnderscoresToCamelCase(field->name(), true)); 1715 printer->Indent(); 1716 // We clear only allocated objects in oneofs 1717 if (!IsStringOrMessage(field)) { 1718 printer->Print( 1719 "// No need to clear\n"); 1720 } else { 1721 field_generators_.get(field).GenerateClearingCode(printer); 1722 } 1723 printer->Print( 1724 "break;\n"); 1725 printer->Outdent(); 1726 printer->Print( 1727 "}\n"); 1728 } 1729 printer->Print( 1730 "case $cap_oneof_name$_NOT_SET: {\n" 1731 " break;\n" 1732 "}\n", 1733 "cap_oneof_name", 1734 ToUpper(descriptor_->oneof_decl(i)->name())); 1735 printer->Outdent(); 1736 printer->Print( 1737 "}\n" 1738 "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n", 1739 "oneof_index", SimpleItoa(i), 1740 "cap_oneof_name", 1741 ToUpper(descriptor_->oneof_decl(i)->name())); 1742 printer->Outdent(); 1743 printer->Print( 1744 "}\n" 1745 "\n"); 1746 } 1747} 1748 1749void MessageGenerator:: 1750GenerateSwap(io::Printer* printer) { 1751 // Generate the Swap member function. 1752 printer->Print("void $classname$::Swap($classname$* other) {\n", 1753 "classname", classname_); 1754 printer->Indent(); 1755 printer->Print("if (other != this) {\n"); 1756 printer->Indent(); 1757 1758 if (HasGeneratedMethods(descriptor_->file())) { 1759 for (int i = 0; i < descriptor_->field_count(); i++) { 1760 const FieldDescriptor* field = descriptor_->field(i); 1761 field_generators_.get(field).GenerateSwappingCode(printer); 1762 } 1763 1764 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1765 printer->Print( 1766 "std::swap($oneof_name$_, other->$oneof_name$_);\n" 1767 "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n", 1768 "oneof_name", descriptor_->oneof_decl(i)->name(), 1769 "i", SimpleItoa(i)); 1770 } 1771 1772 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) { 1773 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", 1774 "i", SimpleItoa(i)); 1775 } 1776 1777 if (UseUnknownFieldSet(descriptor_->file())) { 1778 printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n"); 1779 } else { 1780 printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n"); 1781 } 1782 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); 1783 if (descriptor_->extension_range_count() > 0) { 1784 printer->Print("_extensions_.Swap(&other->_extensions_);\n"); 1785 } 1786 } else { 1787 printer->Print("GetReflection()->Swap(this, other);"); 1788 } 1789 1790 printer->Outdent(); 1791 printer->Print("}\n"); 1792 printer->Outdent(); 1793 printer->Print("}\n"); 1794} 1795 1796void MessageGenerator:: 1797GenerateMergeFrom(io::Printer* printer) { 1798 if (HasDescriptorMethods(descriptor_->file())) { 1799 // Generate the generalized MergeFrom (aka that which takes in the Message 1800 // base class as a parameter). 1801 printer->Print( 1802 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n" 1803 " GOOGLE_CHECK_NE(&from, this);\n", 1804 "classname", classname_); 1805 printer->Indent(); 1806 1807 // Cast the message to the proper type. If we find that the message is 1808 // *not* of the proper type, we can still call Merge via the reflection 1809 // system, as the GOOGLE_CHECK above ensured that we have the same descriptor 1810 // for each message. 1811 printer->Print( 1812 "const $classname$* source =\n" 1813 " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n" 1814 " &from);\n" 1815 "if (source == NULL) {\n" 1816 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" 1817 "} else {\n" 1818 " MergeFrom(*source);\n" 1819 "}\n", 1820 "classname", classname_); 1821 1822 printer->Outdent(); 1823 printer->Print("}\n\n"); 1824 } else { 1825 // Generate CheckTypeAndMergeFrom(). 1826 printer->Print( 1827 "void $classname$::CheckTypeAndMergeFrom(\n" 1828 " const ::google::protobuf::MessageLite& from) {\n" 1829 " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n" 1830 "}\n" 1831 "\n", 1832 "classname", classname_); 1833 } 1834 1835 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. 1836 printer->Print( 1837 "void $classname$::MergeFrom(const $classname$& from) {\n" 1838 " GOOGLE_CHECK_NE(&from, this);\n", 1839 "classname", classname_); 1840 printer->Indent(); 1841 1842 // Merge Repeated fields. These fields do not require a 1843 // check as we can simply iterate over them. 1844 for (int i = 0; i < descriptor_->field_count(); ++i) { 1845 const FieldDescriptor* field = descriptor_->field(i); 1846 1847 if (field->is_repeated()) { 1848 field_generators_.get(field).GenerateMergingCode(printer); 1849 } 1850 } 1851 1852 // Merge oneof fields. Oneof field requires oneof case check. 1853 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { 1854 printer->Print( 1855 "switch (from.$oneofname$_case()) {\n", 1856 "oneofname", descriptor_->oneof_decl(i)->name()); 1857 printer->Indent(); 1858 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 1859 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 1860 printer->Print( 1861 "case k$field_name$: {\n", 1862 "field_name", UnderscoresToCamelCase(field->name(), true)); 1863 printer->Indent(); 1864 field_generators_.get(field).GenerateMergingCode(printer); 1865 printer->Print( 1866 "break;\n"); 1867 printer->Outdent(); 1868 printer->Print( 1869 "}\n"); 1870 } 1871 printer->Print( 1872 "case $cap_oneof_name$_NOT_SET: {\n" 1873 " break;\n" 1874 "}\n", 1875 "cap_oneof_name", 1876 ToUpper(descriptor_->oneof_decl(i)->name())); 1877 printer->Outdent(); 1878 printer->Print( 1879 "}\n"); 1880 } 1881 1882 // Merge Optional and Required fields (after a _has_bit check). 1883 int last_index = -1; 1884 1885 for (int i = 0; i < descriptor_->field_count(); ++i) { 1886 const FieldDescriptor* field = descriptor_->field(i); 1887 1888 if (!field->is_repeated() && !field->containing_oneof()) { 1889 // See above in GenerateClear for an explanation of this. 1890 if (i / 8 != last_index / 8 || last_index < 0) { 1891 if (last_index >= 0) { 1892 printer->Outdent(); 1893 printer->Print("}\n"); 1894 } 1895 printer->Print( 1896 "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 1897 "index", SimpleItoa(field->index())); 1898 printer->Indent(); 1899 } 1900 1901 last_index = i; 1902 1903 printer->Print( 1904 "if (from.has_$name$()) {\n", 1905 "name", FieldName(field)); 1906 printer->Indent(); 1907 1908 field_generators_.get(field).GenerateMergingCode(printer); 1909 1910 printer->Outdent(); 1911 printer->Print("}\n"); 1912 } 1913 } 1914 1915 if (last_index >= 0) { 1916 printer->Outdent(); 1917 printer->Print("}\n"); 1918 } 1919 1920 if (descriptor_->extension_range_count() > 0) { 1921 printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); 1922 } 1923 1924 if (UseUnknownFieldSet(descriptor_->file())) { 1925 printer->Print( 1926 "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"); 1927 } else { 1928 printer->Print( 1929 "mutable_unknown_fields()->append(from.unknown_fields());\n"); 1930 } 1931 1932 printer->Outdent(); 1933 printer->Print("}\n"); 1934} 1935 1936void MessageGenerator:: 1937GenerateCopyFrom(io::Printer* printer) { 1938 if (HasDescriptorMethods(descriptor_->file())) { 1939 // Generate the generalized CopyFrom (aka that which takes in the Message 1940 // base class as a parameter). 1941 printer->Print( 1942 "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n", 1943 "classname", classname_); 1944 printer->Indent(); 1945 1946 printer->Print( 1947 "if (&from == this) return;\n" 1948 "Clear();\n" 1949 "MergeFrom(from);\n"); 1950 1951 printer->Outdent(); 1952 printer->Print("}\n\n"); 1953 } 1954 1955 // Generate the class-specific CopyFrom. 1956 printer->Print( 1957 "void $classname$::CopyFrom(const $classname$& from) {\n", 1958 "classname", classname_); 1959 printer->Indent(); 1960 1961 printer->Print( 1962 "if (&from == this) return;\n" 1963 "Clear();\n" 1964 "MergeFrom(from);\n"); 1965 1966 printer->Outdent(); 1967 printer->Print("}\n"); 1968} 1969 1970void MessageGenerator:: 1971GenerateMergeFromCodedStream(io::Printer* printer) { 1972 if (descriptor_->options().message_set_wire_format()) { 1973 // Special-case MessageSet. 1974 printer->Print( 1975 "bool $classname$::MergePartialFromCodedStream(\n" 1976 " ::google::protobuf::io::CodedInputStream* input) {\n", 1977 "classname", classname_); 1978 1979 PrintHandlingOptionalStaticInitializers( 1980 descriptor_->file(), printer, 1981 // With static initializers. 1982 " return _extensions_.ParseMessageSet(input, default_instance_,\n" 1983 " mutable_unknown_fields());\n", 1984 // Without. 1985 " return _extensions_.ParseMessageSet(input, &default_instance(),\n" 1986 " mutable_unknown_fields());\n", 1987 // Vars. 1988 "classname", classname_); 1989 1990 printer->Print( 1991 "}\n"); 1992 return; 1993 } 1994 1995 printer->Print( 1996 "bool $classname$::MergePartialFromCodedStream(\n" 1997 " ::google::protobuf::io::CodedInputStream* input) {\n" 1998 "#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n" 1999 " ::google::protobuf::uint32 tag;\n", 2000 "classname", classname_); 2001 2002 if (!UseUnknownFieldSet(descriptor_->file())) { 2003 printer->Print( 2004 " ::google::protobuf::io::StringOutputStream unknown_fields_string(\n" 2005 " mutable_unknown_fields());\n" 2006 " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n" 2007 " &unknown_fields_string);\n"); 2008 } 2009 2010 printer->Print( 2011 " // @@protoc_insertion_point(parse_start:$full_name$)\n", 2012 "full_name", descriptor_->full_name()); 2013 2014 printer->Indent(); 2015 printer->Print("for (;;) {\n"); 2016 printer->Indent(); 2017 2018 scoped_array<const FieldDescriptor*> ordered_fields( 2019 SortFieldsByNumber(descriptor_)); 2020 uint32 maxtag = descriptor_->field_count() == 0 ? 0 : 2021 WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]); 2022 const int kCutoff0 = 127; // fits in 1-byte varint 2023 const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint 2024 printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = " 2025 "input->ReadTagWithCutoff($max$);\n" 2026 "tag = p.first;\n" 2027 "if (!p.second) goto handle_unusual;\n", 2028 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 : 2029 (maxtag <= kCutoff1 ? kCutoff1 : 2030 maxtag))); 2031 if (descriptor_->field_count() > 0) { 2032 // We don't even want to print the switch() if we have no fields because 2033 // MSVC dislikes switch() statements that contain only a default value. 2034 2035 // Note: If we just switched on the tag rather than the field number, we 2036 // could avoid the need for the if() to check the wire type at the beginning 2037 // of each case. However, this is actually a bit slower in practice as it 2038 // creates a jump table that is 8x larger and sparser, and meanwhile the 2039 // if()s are highly predictable. 2040 printer->Print("switch (::google::protobuf::internal::WireFormatLite::" 2041 "GetTagFieldNumber(tag)) {\n"); 2042 2043 printer->Indent(); 2044 2045 for (int i = 0; i < descriptor_->field_count(); i++) { 2046 const FieldDescriptor* field = ordered_fields[i]; 2047 2048 PrintFieldComment(printer, field); 2049 2050 printer->Print( 2051 "case $number$: {\n", 2052 "number", SimpleItoa(field->number())); 2053 printer->Indent(); 2054 const FieldGenerator& field_generator = field_generators_.get(field); 2055 2056 // Emit code to parse the common, expected case. 2057 printer->Print("if (tag == $commontag$) {\n", 2058 "commontag", SimpleItoa(WireFormat::MakeTag(field))); 2059 2060 if (i > 0 || (field->is_repeated() && !field->options().packed())) { 2061 printer->Print( 2062 " parse_$name$:\n", 2063 "name", field->name()); 2064 } 2065 2066 printer->Indent(); 2067 if (field->options().packed()) { 2068 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 2069 } else { 2070 field_generator.GenerateMergeFromCodedStream(printer); 2071 } 2072 printer->Outdent(); 2073 2074 // Emit code to parse unexpectedly packed or unpacked values. 2075 if (field->is_packable() && field->options().packed()) { 2076 internal::WireFormatLite::WireType wiretype = 2077 WireFormat::WireTypeForFieldType(field->type()); 2078 printer->Print("} else if (tag == $uncommontag$) {\n", 2079 "uncommontag", SimpleItoa( 2080 internal::WireFormatLite::MakeTag( 2081 field->number(), wiretype))); 2082 printer->Indent(); 2083 field_generator.GenerateMergeFromCodedStream(printer); 2084 printer->Outdent(); 2085 } else if (field->is_packable() && !field->options().packed()) { 2086 internal::WireFormatLite::WireType wiretype = 2087 internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED; 2088 printer->Print("} else if (tag == $uncommontag$) {\n", 2089 "uncommontag", SimpleItoa( 2090 internal::WireFormatLite::MakeTag( 2091 field->number(), wiretype))); 2092 printer->Indent(); 2093 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 2094 printer->Outdent(); 2095 } 2096 2097 printer->Print( 2098 "} else {\n" 2099 " goto handle_unusual;\n" 2100 "}\n"); 2101 2102 // switch() is slow since it can't be predicted well. Insert some if()s 2103 // here that attempt to predict the next tag. 2104 if (field->is_repeated() && !field->options().packed()) { 2105 // Expect repeats of this field. 2106 printer->Print( 2107 "if (input->ExpectTag($tag$)) goto parse_$name$;\n", 2108 "tag", SimpleItoa(WireFormat::MakeTag(field)), 2109 "name", field->name()); 2110 } 2111 2112 if (i + 1 < descriptor_->field_count()) { 2113 // Expect the next field in order. 2114 const FieldDescriptor* next_field = ordered_fields[i + 1]; 2115 printer->Print( 2116 "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", 2117 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), 2118 "next_name", next_field->name()); 2119 } else { 2120 // Expect EOF. 2121 // TODO(kenton): Expect group end-tag? 2122 printer->Print( 2123 "if (input->ExpectAtEnd()) goto success;\n"); 2124 } 2125 2126 printer->Print( 2127 "break;\n"); 2128 2129 printer->Outdent(); 2130 printer->Print("}\n\n"); 2131 } 2132 2133 printer->Print("default: {\n"); 2134 printer->Indent(); 2135 } 2136 2137 printer->Outdent(); 2138 printer->Print("handle_unusual:\n"); 2139 printer->Indent(); 2140 // If tag is 0 or an end-group tag then this must be the end of the message. 2141 printer->Print( 2142 "if (tag == 0 ||\n" 2143 " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" 2144 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" 2145 " goto success;\n" 2146 "}\n"); 2147 2148 // Handle extension ranges. 2149 if (descriptor_->extension_range_count() > 0) { 2150 printer->Print( 2151 "if ("); 2152 for (int i = 0; i < descriptor_->extension_range_count(); i++) { 2153 const Descriptor::ExtensionRange* range = 2154 descriptor_->extension_range(i); 2155 if (i > 0) printer->Print(" ||\n "); 2156 2157 uint32 start_tag = WireFormatLite::MakeTag( 2158 range->start, static_cast<WireFormatLite::WireType>(0)); 2159 uint32 end_tag = WireFormatLite::MakeTag( 2160 range->end, static_cast<WireFormatLite::WireType>(0)); 2161 2162 if (range->end > FieldDescriptor::kMaxNumber) { 2163 printer->Print( 2164 "($start$u <= tag)", 2165 "start", SimpleItoa(start_tag)); 2166 } else { 2167 printer->Print( 2168 "($start$u <= tag && tag < $end$u)", 2169 "start", SimpleItoa(start_tag), 2170 "end", SimpleItoa(end_tag)); 2171 } 2172 } 2173 printer->Print(") {\n"); 2174 if (UseUnknownFieldSet(descriptor_->file())) { 2175 PrintHandlingOptionalStaticInitializers( 2176 descriptor_->file(), printer, 2177 // With static initializers. 2178 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n" 2179 " mutable_unknown_fields()));\n", 2180 // Without. 2181 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n" 2182 " mutable_unknown_fields()));\n"); 2183 } else { 2184 PrintHandlingOptionalStaticInitializers( 2185 descriptor_->file(), printer, 2186 // With static initializers. 2187 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n" 2188 " &unknown_fields_stream));\n", 2189 // Without. 2190 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n" 2191 " &unknown_fields_stream));\n"); 2192 } 2193 printer->Print( 2194 " continue;\n" 2195 "}\n"); 2196 } 2197 2198 // We really don't recognize this tag. Skip it. 2199 if (UseUnknownFieldSet(descriptor_->file())) { 2200 printer->Print( 2201 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" 2202 " input, tag, mutable_unknown_fields()));\n"); 2203 } else { 2204 printer->Print( 2205 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n" 2206 " input, tag, &unknown_fields_stream));\n"); 2207 } 2208 2209 if (descriptor_->field_count() > 0) { 2210 printer->Print("break;\n"); 2211 printer->Outdent(); 2212 printer->Print("}\n"); // default: 2213 printer->Outdent(); 2214 printer->Print("}\n"); // switch 2215 } 2216 2217 printer->Outdent(); 2218 printer->Outdent(); 2219 printer->Print( 2220 " }\n" // for (;;) 2221 "success:\n" 2222 " // @@protoc_insertion_point(parse_success:$full_name$)\n" 2223 " return true;\n" 2224 "failure:\n" 2225 " // @@protoc_insertion_point(parse_failure:$full_name$)\n" 2226 " return false;\n" 2227 "#undef DO_\n" 2228 "}\n", "full_name", descriptor_->full_name()); 2229} 2230 2231void MessageGenerator::GenerateSerializeOneField( 2232 io::Printer* printer, const FieldDescriptor* field, bool to_array) { 2233 PrintFieldComment(printer, field); 2234 2235 if (!field->is_repeated()) { 2236 printer->Print( 2237 "if (has_$name$()) {\n", 2238 "name", FieldName(field)); 2239 printer->Indent(); 2240 } 2241 2242 if (to_array) { 2243 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray( 2244 printer); 2245 } else { 2246 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); 2247 } 2248 2249 if (!field->is_repeated()) { 2250 printer->Outdent(); 2251 printer->Print("}\n"); 2252 } 2253 printer->Print("\n"); 2254} 2255 2256void MessageGenerator::GenerateSerializeOneExtensionRange( 2257 io::Printer* printer, const Descriptor::ExtensionRange* range, 2258 bool to_array) { 2259 map<string, string> vars; 2260 vars["start"] = SimpleItoa(range->start); 2261 vars["end"] = SimpleItoa(range->end); 2262 printer->Print(vars, 2263 "// Extension range [$start$, $end$)\n"); 2264 if (to_array) { 2265 printer->Print(vars, 2266 "target = _extensions_.SerializeWithCachedSizesToArray(\n" 2267 " $start$, $end$, target);\n\n"); 2268 } else { 2269 printer->Print(vars, 2270 "_extensions_.SerializeWithCachedSizes(\n" 2271 " $start$, $end$, output);\n\n"); 2272 } 2273} 2274 2275void MessageGenerator:: 2276GenerateSerializeWithCachedSizes(io::Printer* printer) { 2277 if (descriptor_->options().message_set_wire_format()) { 2278 // Special-case MessageSet. 2279 printer->Print( 2280 "void $classname$::SerializeWithCachedSizes(\n" 2281 " ::google::protobuf::io::CodedOutputStream* output) const {\n" 2282 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", 2283 "classname", classname_); 2284 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file())); 2285 printer->Print( 2286 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n" 2287 " unknown_fields(), output);\n"); 2288 printer->Print( 2289 "}\n"); 2290 return; 2291 } 2292 2293 printer->Print( 2294 "void $classname$::SerializeWithCachedSizes(\n" 2295 " ::google::protobuf::io::CodedOutputStream* output) const {\n", 2296 "classname", classname_); 2297 printer->Indent(); 2298 2299 printer->Print( 2300 "// @@protoc_insertion_point(serialize_start:$full_name$)\n", 2301 "full_name", descriptor_->full_name()); 2302 2303 GenerateSerializeWithCachedSizesBody(printer, false); 2304 2305 printer->Print( 2306 "// @@protoc_insertion_point(serialize_end:$full_name$)\n", 2307 "full_name", descriptor_->full_name()); 2308 2309 printer->Outdent(); 2310 printer->Print( 2311 "}\n"); 2312} 2313 2314void MessageGenerator:: 2315GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { 2316 if (descriptor_->options().message_set_wire_format()) { 2317 // Special-case MessageSet. 2318 printer->Print( 2319 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 2320 " ::google::protobuf::uint8* target) const {\n" 2321 " target =\n" 2322 " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n", 2323 "classname", classname_); 2324 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file())); 2325 printer->Print( 2326 " target = ::google::protobuf::internal::WireFormat::\n" 2327 " SerializeUnknownMessageSetItemsToArray(\n" 2328 " unknown_fields(), target);\n"); 2329 printer->Print( 2330 " return target;\n" 2331 "}\n"); 2332 return; 2333 } 2334 2335 printer->Print( 2336 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 2337 " ::google::protobuf::uint8* target) const {\n", 2338 "classname", classname_); 2339 printer->Indent(); 2340 2341 printer->Print( 2342 "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n", 2343 "full_name", descriptor_->full_name()); 2344 2345 GenerateSerializeWithCachedSizesBody(printer, true); 2346 2347 printer->Print( 2348 "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n", 2349 "full_name", descriptor_->full_name()); 2350 2351 printer->Outdent(); 2352 printer->Print( 2353 " return target;\n" 2354 "}\n"); 2355} 2356 2357void MessageGenerator:: 2358GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { 2359 scoped_array<const FieldDescriptor*> ordered_fields( 2360 SortFieldsByNumber(descriptor_)); 2361 2362 vector<const Descriptor::ExtensionRange*> sorted_extensions; 2363 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { 2364 sorted_extensions.push_back(descriptor_->extension_range(i)); 2365 } 2366 sort(sorted_extensions.begin(), sorted_extensions.end(), 2367 ExtensionRangeSorter()); 2368 2369 // Merge the fields and the extension ranges, both sorted by field number. 2370 int i, j; 2371 for (i = 0, j = 0; 2372 i < descriptor_->field_count() || j < sorted_extensions.size(); 2373 ) { 2374 if (i == descriptor_->field_count()) { 2375 GenerateSerializeOneExtensionRange(printer, 2376 sorted_extensions[j++], 2377 to_array); 2378 } else if (j == sorted_extensions.size()) { 2379 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 2380 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { 2381 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 2382 } else { 2383 GenerateSerializeOneExtensionRange(printer, 2384 sorted_extensions[j++], 2385 to_array); 2386 } 2387 } 2388 2389 if (UseUnknownFieldSet(descriptor_->file())) { 2390 printer->Print("if (!unknown_fields().empty()) {\n"); 2391 printer->Indent(); 2392 if (to_array) { 2393 printer->Print( 2394 "target = " 2395 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" 2396 " unknown_fields(), target);\n"); 2397 } else { 2398 printer->Print( 2399 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" 2400 " unknown_fields(), output);\n"); 2401 } 2402 printer->Outdent(); 2403 2404 printer->Print( 2405 "}\n"); 2406 } else { 2407 printer->Print( 2408 "output->WriteRaw(unknown_fields().data(),\n" 2409 " unknown_fields().size());\n"); 2410 } 2411} 2412 2413void MessageGenerator:: 2414GenerateByteSize(io::Printer* printer) { 2415 if (descriptor_->options().message_set_wire_format()) { 2416 // Special-case MessageSet. 2417 printer->Print( 2418 "int $classname$::ByteSize() const {\n" 2419 " int total_size = _extensions_.MessageSetByteSize();\n", 2420 "classname", classname_); 2421 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file())); 2422 printer->Print( 2423 " total_size += ::google::protobuf::internal::WireFormat::\n" 2424 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"); 2425 printer->Print( 2426 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 2427 " _cached_size_ = total_size;\n" 2428 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 2429 " return total_size;\n" 2430 "}\n"); 2431 return; 2432 } 2433 2434 printer->Print( 2435 "int $classname$::ByteSize() const {\n", 2436 "classname", classname_); 2437 printer->Indent(); 2438 printer->Print( 2439 "int total_size = 0;\n" 2440 "\n"); 2441 2442 int last_index = -1; 2443 2444 for (int i = 0; i < descriptor_->field_count(); i++) { 2445 const FieldDescriptor* field = descriptor_->field(i); 2446 2447 if (!field->is_repeated() && !field->containing_oneof()) { 2448 // See above in GenerateClear for an explanation of this. 2449 // TODO(kenton): Share code? Unclear how to do so without 2450 // over-engineering. 2451 if ((i / 8) != (last_index / 8) || 2452 last_index < 0) { 2453 if (last_index >= 0) { 2454 printer->Outdent(); 2455 printer->Print("}\n"); 2456 } 2457 printer->Print( 2458 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 2459 "index", SimpleItoa(field->index())); 2460 printer->Indent(); 2461 } 2462 last_index = i; 2463 2464 PrintFieldComment(printer, field); 2465 2466 printer->Print( 2467 "if (has_$name$()) {\n", 2468 "name", FieldName(field)); 2469 printer->Indent(); 2470 2471 field_generators_.get(field).GenerateByteSize(printer); 2472 2473 printer->Outdent(); 2474 printer->Print( 2475 "}\n" 2476 "\n"); 2477 } 2478 } 2479 2480 if (last_index >= 0) { 2481 printer->Outdent(); 2482 printer->Print("}\n"); 2483 } 2484 2485 // Repeated fields don't use _has_bits_ so we count them in a separate 2486 // pass. 2487 for (int i = 0; i < descriptor_->field_count(); i++) { 2488 const FieldDescriptor* field = descriptor_->field(i); 2489 2490 if (field->is_repeated()) { 2491 PrintFieldComment(printer, field); 2492 field_generators_.get(field).GenerateByteSize(printer); 2493 printer->Print("\n"); 2494 } 2495 } 2496 2497 // Fields inside a oneof don't use _has_bits_ so we count them in a separate 2498 // pass. 2499 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 2500 printer->Print( 2501 "switch ($oneofname$_case()) {\n", 2502 "oneofname", descriptor_->oneof_decl(i)->name()); 2503 printer->Indent(); 2504 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 2505 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 2506 PrintFieldComment(printer, field); 2507 printer->Print( 2508 "case k$field_name$: {\n", 2509 "field_name", UnderscoresToCamelCase(field->name(), true)); 2510 printer->Indent(); 2511 field_generators_.get(field).GenerateByteSize(printer); 2512 printer->Print( 2513 "break;\n"); 2514 printer->Outdent(); 2515 printer->Print( 2516 "}\n"); 2517 } 2518 printer->Print( 2519 "case $cap_oneof_name$_NOT_SET: {\n" 2520 " break;\n" 2521 "}\n", 2522 "cap_oneof_name", 2523 ToUpper(descriptor_->oneof_decl(i)->name())); 2524 printer->Outdent(); 2525 printer->Print( 2526 "}\n"); 2527 } 2528 2529 if (descriptor_->extension_range_count() > 0) { 2530 printer->Print( 2531 "total_size += _extensions_.ByteSize();\n" 2532 "\n"); 2533 } 2534 2535 if (UseUnknownFieldSet(descriptor_->file())) { 2536 printer->Print("if (!unknown_fields().empty()) {\n"); 2537 printer->Indent(); 2538 printer->Print( 2539 "total_size +=\n" 2540 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" 2541 " unknown_fields());\n"); 2542 printer->Outdent(); 2543 printer->Print("}\n"); 2544 } else { 2545 printer->Print( 2546 "total_size += unknown_fields().size();\n" 2547 "\n"); 2548 } 2549 2550 // We update _cached_size_ even though this is a const method. In theory, 2551 // this is not thread-compatible, because concurrent writes have undefined 2552 // results. In practice, since any concurrent writes will be writing the 2553 // exact same value, it works on all common processors. In a future version 2554 // of C++, _cached_size_ should be made into an atomic<int>. 2555 printer->Print( 2556 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 2557 "_cached_size_ = total_size;\n" 2558 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 2559 "return total_size;\n"); 2560 2561 printer->Outdent(); 2562 printer->Print("}\n"); 2563} 2564 2565void MessageGenerator:: 2566GenerateIsInitialized(io::Printer* printer) { 2567 printer->Print( 2568 "bool $classname$::IsInitialized() const {\n", 2569 "classname", classname_); 2570 printer->Indent(); 2571 2572 // Check that all required fields in this message are set. We can do this 2573 // most efficiently by checking 32 "has bits" at a time. 2574 int has_bits_array_size = (descriptor_->field_count() + 31) / 32; 2575 for (int i = 0; i < has_bits_array_size; i++) { 2576 uint32 mask = 0; 2577 for (int bit = 0; bit < 32; bit++) { 2578 int index = i * 32 + bit; 2579 if (index >= descriptor_->field_count()) break; 2580 const FieldDescriptor* field = descriptor_->field(index); 2581 2582 if (field->is_required()) { 2583 mask |= 1 << bit; 2584 } 2585 } 2586 2587 if (mask != 0) { 2588 char buffer[kFastToBufferSize]; 2589 printer->Print( 2590 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", 2591 "i", SimpleItoa(i), 2592 "mask", FastHex32ToBuffer(mask, buffer)); 2593 } 2594 } 2595 2596 // Now check that all embedded messages are initialized. 2597 printer->Print("\n"); 2598 for (int i = 0; i < descriptor_->field_count(); i++) { 2599 const FieldDescriptor* field = descriptor_->field(i); 2600 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 2601 !ShouldIgnoreRequiredFieldCheck(field) && 2602 HasRequiredFields(field->message_type())) { 2603 if (field->is_repeated()) { 2604 printer->Print( 2605 "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))" 2606 " return false;\n", 2607 "name", FieldName(field)); 2608 } else { 2609 if (field->options().weak()) { 2610 // For weak fields, use the data member (google::protobuf::Message*) instead 2611 // of the getter to avoid a link dependency on the weak message type 2612 // which is only forward declared. 2613 printer->Print( 2614 "if (has_$name$()) {\n" 2615 " if (!this->$name$_->IsInitialized()) return false;\n" 2616 "}\n", 2617 "name", FieldName(field)); 2618 } else { 2619 printer->Print( 2620 "if (has_$name$()) {\n" 2621 " if (!this->$name$().IsInitialized()) return false;\n" 2622 "}\n", 2623 "name", FieldName(field)); 2624 } 2625 } 2626 } 2627 } 2628 2629 if (descriptor_->extension_range_count() > 0) { 2630 printer->Print( 2631 "\n" 2632 "if (!_extensions_.IsInitialized()) return false;"); 2633 } 2634 2635 printer->Outdent(); 2636 printer->Print( 2637 " return true;\n" 2638 "}\n"); 2639} 2640 2641 2642} // namespace cpp 2643} // namespace compiler 2644} // namespace protobuf 2645} // namespace google 2646