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