PageRenderTime 132ms CodeModel.GetById 3ms app.highlight 117ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1933 lines | 1446 code | 273 blank | 214 comment | 208 complexity | 6e660f457bf4881f898a9296f8511e20 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// Protocol Buffers - Google's data interchange format
   2// Copyright 2008 Google Inc.  All rights reserved.
   3// http://code.google.com/p/protobuf/
   4//
   5// Redistribution and use in source and binary forms, with or without
   6// modification, are permitted provided that the following conditions are
   7// met:
   8//
   9//     * Redistributions of source code must retain the above copyright
  10// notice, this list of conditions and the following disclaimer.
  11//     * Redistributions in binary form must reproduce the above
  12// copyright notice, this list of conditions and the following disclaimer
  13// in the documentation and/or other materials provided with the
  14// distribution.
  15//     * Neither the name of Google Inc. nor the names of its
  16// contributors may be used to endorse or promote products derived from
  17// this software without specific prior written permission.
  18//
  19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30
  31// Author: kenton@google.com (Kenton Varda)
  32//  Based on original Protocol Buffers design by
  33//  Sanjay Ghemawat, Jeff Dean, and others.
  34
  35#include <algorithm>
  36#include <google/protobuf/stubs/hash.h>
  37#include <map>
  38#include <utility>
  39#include <vector>
  40#include <google/protobuf/compiler/cpp/cpp_message.h>
  41#include <google/protobuf/compiler/cpp/cpp_field.h>
  42#include <google/protobuf/compiler/cpp/cpp_enum.h>
  43#include <google/protobuf/compiler/cpp/cpp_extension.h>
  44#include <google/protobuf/compiler/cpp/cpp_helpers.h>
  45#include <google/protobuf/stubs/strutil.h>
  46#include <google/protobuf/io/printer.h>
  47#include <google/protobuf/io/coded_stream.h>
  48#include <google/protobuf/wire_format.h>
  49#include <google/protobuf/descriptor.pb.h>
  50
  51namespace google {
  52namespace protobuf {
  53namespace compiler {
  54namespace cpp {
  55
  56using internal::WireFormat;
  57using internal::WireFormatLite;
  58
  59namespace {
  60
  61void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
  62  // Print the field's proto-syntax definition as a comment.  We don't want to
  63  // print group bodies so we cut off after the first line.
  64  string def = field->DebugString();
  65  printer->Print("// $def$\n",
  66    "def", def.substr(0, def.find_first_of('\n')));
  67}
  68
  69struct FieldOrderingByNumber {
  70  inline bool operator()(const FieldDescriptor* a,
  71                         const FieldDescriptor* b) const {
  72    return a->number() < b->number();
  73  }
  74};
  75
  76const char* kWireTypeNames[] = {
  77  "VARINT",
  78  "FIXED64",
  79  "LENGTH_DELIMITED",
  80  "START_GROUP",
  81  "END_GROUP",
  82  "FIXED32",
  83};
  84
  85// Sort the fields of the given Descriptor by number into a new[]'d array
  86// and return it.
  87const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
  88  const FieldDescriptor** fields =
  89    new const FieldDescriptor*[descriptor->field_count()];
  90  for (int i = 0; i < descriptor->field_count(); i++) {
  91    fields[i] = descriptor->field(i);
  92  }
  93  sort(fields, fields + descriptor->field_count(),
  94       FieldOrderingByNumber());
  95  return fields;
  96}
  97
  98// Functor for sorting extension ranges by their "start" field number.
  99struct ExtensionRangeSorter {
 100  bool operator()(const Descriptor::ExtensionRange* left,
 101                  const Descriptor::ExtensionRange* right) const {
 102    return left->start < right->start;
 103  }
 104};
 105
 106// Returns true if the message type has any required fields.  If it doesn't,
 107// we can optimize out calls to its IsInitialized() method.
 108//
 109// already_seen is used to avoid checking the same type multiple times
 110// (and also to protect against recursion).
 111static bool HasRequiredFields(
 112    const Descriptor* type,
 113    hash_set<const Descriptor*>* already_seen) {
 114  if (already_seen->count(type) > 0) {
 115    // Since the first occurrence of a required field causes the whole
 116    // function to return true, we can assume that if the type is already
 117    // in the cache it didn't have any required fields.
 118    return false;
 119  }
 120  already_seen->insert(type);
 121
 122  // If the type has extensions, an extension with message type could contain
 123  // required fields, so we have to be conservative and assume such an
 124  // extension exists.
 125  if (type->extension_range_count() > 0) return true;
 126
 127  for (int i = 0; i < type->field_count(); i++) {
 128    const FieldDescriptor* field = type->field(i);
 129    if (field->is_required()) {
 130      return true;
 131    }
 132    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 133      if (HasRequiredFields(field->message_type(), already_seen)) {
 134        return true;
 135      }
 136    }
 137  }
 138
 139  return false;
 140}
 141
 142static bool HasRequiredFields(const Descriptor* type) {
 143  hash_set<const Descriptor*> already_seen;
 144  return HasRequiredFields(type, &already_seen);
 145}
 146
 147// This returns an estimate of the compiler's alignment for the field.  This
 148// can't guarantee to be correct because the generated code could be compiled on
 149// different systems with different alignment rules.  The estimates below assume
 150// 64-bit pointers.
 151int EstimateAlignmentSize(const FieldDescriptor* field) {
 152  if (field == NULL) return 0;
 153  if (field->is_repeated()) return 8;
 154  switch (field->cpp_type()) {
 155    case FieldDescriptor::CPPTYPE_BOOL:
 156      return 1;
 157
 158    case FieldDescriptor::CPPTYPE_INT32:
 159    case FieldDescriptor::CPPTYPE_UINT32:
 160    case FieldDescriptor::CPPTYPE_ENUM:
 161    case FieldDescriptor::CPPTYPE_FLOAT:
 162      return 4;
 163
 164    case FieldDescriptor::CPPTYPE_INT64:
 165    case FieldDescriptor::CPPTYPE_UINT64:
 166    case FieldDescriptor::CPPTYPE_DOUBLE:
 167    case FieldDescriptor::CPPTYPE_STRING:
 168    case FieldDescriptor::CPPTYPE_MESSAGE:
 169      return 8;
 170  }
 171  GOOGLE_LOG(FATAL) << "Can't get here.";
 172  return -1;  // Make compiler happy.
 173}
 174
 175// FieldGroup is just a helper for OptimizePadding below.  It holds a vector of
 176// fields that are grouped together because they have compatible alignment, and
 177// a preferred location in the final field ordering.
 178class FieldGroup {
 179 public:
 180  FieldGroup()
 181      : preferred_location_(0) {}
 182
 183  // A group with a single field.
 184  FieldGroup(float preferred_location, const FieldDescriptor* field)
 185      : preferred_location_(preferred_location),
 186        fields_(1, field) {}
 187
 188  // Append the fields in 'other' to this group.
 189  void Append(const FieldGroup& other) {
 190    if (other.fields_.empty()) {
 191      return;
 192    }
 193    // Preferred location is the average among all the fields, so we weight by
 194    // the number of fields on each FieldGroup object.
 195    preferred_location_ =
 196        (preferred_location_ * fields_.size() +
 197         (other.preferred_location_ * other.fields_.size())) /
 198        (fields_.size() + other.fields_.size());
 199    fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
 200  }
 201
 202  void SetPreferredLocation(float location) { preferred_location_ = location; }
 203  const vector<const FieldDescriptor*>& fields() const { return fields_; }
 204
 205  // FieldGroup objects sort by their preferred location.
 206  bool operator<(const FieldGroup& other) const {
 207    return preferred_location_ < other.preferred_location_;
 208  }
 209
 210 private:
 211  // "preferred_location_" is an estimate of where this group should go in the
 212  // final list of fields.  We compute this by taking the average index of each
 213  // field in this group in the original ordering of fields.  This is very
 214  // approximate, but should put this group close to where its member fields
 215  // originally went.
 216  float preferred_location_;
 217  vector<const FieldDescriptor*> fields_;
 218  // We rely on the default copy constructor and operator= so this type can be
 219  // used in a vector.
 220};
 221
 222// Reorder 'fields' so that if the fields are output into a c++ class in the new
 223// order, the alignment padding is minimized.  We try to do this while keeping
 224// each field as close as possible to its original position so that we don't
 225// reduce cache locality much for function that access each field in order.
 226void OptimizePadding(vector<const FieldDescriptor*>* fields) {
 227  // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
 228  vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
 229  for (int i = 0; i < fields->size(); ++i) {
 230    switch (EstimateAlignmentSize((*fields)[i])) {
 231      case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
 232      case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
 233      case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
 234      default:
 235        GOOGLE_LOG(FATAL) << "Unknown alignment size.";
 236    }
 237  }
 238
 239  // Now group fields aligned to 1 byte into sets of 4, and treat those like a
 240  // single field aligned to 4 bytes.
 241  for (int i = 0; i < aligned_to_1.size(); i += 4) {
 242    FieldGroup field_group;
 243    for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
 244      field_group.Append(aligned_to_1[j]);
 245    }
 246    aligned_to_4.push_back(field_group);
 247  }
 248  // Sort by preferred location to keep fields as close to their original
 249  // location as possible.
 250  sort(aligned_to_4.begin(), aligned_to_4.end());
 251
 252  // Now group fields aligned to 4 bytes (or the 4-field groups created above)
 253  // into pairs, and treat those like a single field aligned to 8 bytes.
 254  for (int i = 0; i < aligned_to_4.size(); i += 2) {
 255    FieldGroup field_group;
 256    for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
 257      field_group.Append(aligned_to_4[j]);
 258    }
 259    if (i == aligned_to_4.size() - 1) {
 260      // Move incomplete 4-byte block to the end.
 261      field_group.SetPreferredLocation(fields->size() + 1);
 262    }
 263    aligned_to_8.push_back(field_group);
 264  }
 265  // Sort by preferred location to keep fields as close to their original
 266  // location as possible.
 267  sort(aligned_to_8.begin(), aligned_to_8.end());
 268
 269  // Now pull out all the FieldDescriptors in order.
 270  fields->clear();
 271  for (int i = 0; i < aligned_to_8.size(); ++i) {
 272    fields->insert(fields->end(),
 273                   aligned_to_8[i].fields().begin(),
 274                   aligned_to_8[i].fields().end());
 275  }
 276}
 277
 278}
 279
 280// ===================================================================
 281
 282MessageGenerator::MessageGenerator(const Descriptor* descriptor,
 283                                   const string& dllexport_decl)
 284  : descriptor_(descriptor),
 285    classname_(ClassName(descriptor, false)),
 286    dllexport_decl_(dllexport_decl),
 287    field_generators_(descriptor),
 288    nested_generators_(new scoped_ptr<MessageGenerator>[
 289      descriptor->nested_type_count()]),
 290    enum_generators_(new scoped_ptr<EnumGenerator>[
 291      descriptor->enum_type_count()]),
 292    extension_generators_(new scoped_ptr<ExtensionGenerator>[
 293      descriptor->extension_count()]) {
 294
 295  for (int i = 0; i < descriptor->nested_type_count(); i++) {
 296    nested_generators_[i].reset(
 297      new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
 298  }
 299
 300  for (int i = 0; i < descriptor->enum_type_count(); i++) {
 301    enum_generators_[i].reset(
 302      new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
 303  }
 304
 305  for (int i = 0; i < descriptor->extension_count(); i++) {
 306    extension_generators_[i].reset(
 307      new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
 308  }
 309}
 310
 311MessageGenerator::~MessageGenerator() {}
 312
 313void MessageGenerator::
 314GenerateForwardDeclaration(io::Printer* printer) {
 315  printer->Print("class $classname$;\n",
 316                 "classname", classname_);
 317
 318  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 319    nested_generators_[i]->GenerateForwardDeclaration(printer);
 320  }
 321}
 322
 323void MessageGenerator::
 324GenerateEnumDefinitions(io::Printer* printer) {
 325  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 326    nested_generators_[i]->GenerateEnumDefinitions(printer);
 327  }
 328
 329  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 330    enum_generators_[i]->GenerateDefinition(printer);
 331  }
 332}
 333
 334void MessageGenerator::
 335GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
 336  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 337    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
 338  }
 339  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 340    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
 341  }
 342}
 343
 344void MessageGenerator::
 345GenerateFieldAccessorDeclarations(io::Printer* printer) {
 346  for (int i = 0; i < descriptor_->field_count(); i++) {
 347    const FieldDescriptor* field = descriptor_->field(i);
 348
 349    PrintFieldComment(printer, field);
 350
 351    map<string, string> vars;
 352    SetCommonFieldVariables(field, &vars);
 353    vars["constant_name"] = FieldConstantName(field);
 354
 355    if (field->is_repeated()) {
 356      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
 357    } else {
 358      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
 359    }
 360
 361    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
 362    printer->Print(vars, "static const int $constant_name$ = $number$;\n");
 363
 364    // Generate type-specific accessor declarations.
 365    field_generators_.get(field).GenerateAccessorDeclarations(printer);
 366
 367    printer->Print("\n");
 368  }
 369
 370  if (descriptor_->extension_range_count() > 0) {
 371    // Generate accessors for extensions.  We just call a macro located in
 372    // extension_set.h since the accessors about 80 lines of static code.
 373    printer->Print(
 374      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
 375      "classname", classname_);
 376  }
 377}
 378
 379void MessageGenerator::
 380GenerateFieldAccessorDefinitions(io::Printer* printer) {
 381  printer->Print("// $classname$\n\n", "classname", classname_);
 382
 383  for (int i = 0; i < descriptor_->field_count(); i++) {
 384    const FieldDescriptor* field = descriptor_->field(i);
 385
 386    PrintFieldComment(printer, field);
 387
 388    map<string, string> vars;
 389    SetCommonFieldVariables(field, &vars);
 390
 391    // Generate has_$name$() or $name$_size().
 392    if (field->is_repeated()) {
 393      printer->Print(vars,
 394        "inline int $classname$::$name$_size() const {\n"
 395        "  return $name$_.size();\n"
 396        "}\n");
 397    } else {
 398      // Singular field.
 399      char buffer[kFastToBufferSize];
 400      vars["has_array_index"] = SimpleItoa(field->index() / 32);
 401      vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
 402      printer->Print(vars,
 403        "inline bool $classname$::has_$name$() const {\n"
 404        "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
 405        "}\n"
 406        "inline void $classname$::set_has_$name$() {\n"
 407        "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
 408        "}\n"
 409        "inline void $classname$::clear_has_$name$() {\n"
 410        "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
 411        "}\n"
 412        );
 413    }
 414
 415    // Generate clear_$name$()
 416    printer->Print(vars,
 417      "inline void $classname$::clear_$name$() {\n");
 418
 419    printer->Indent();
 420    field_generators_.get(field).GenerateClearingCode(printer);
 421    printer->Outdent();
 422
 423    if (!field->is_repeated()) {
 424      printer->Print(vars,
 425                     "  clear_has_$name$();\n");
 426    }
 427
 428    printer->Print("}\n");
 429
 430    // Generate type-specific accessors.
 431    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
 432
 433    printer->Print("\n");
 434  }
 435}
 436
 437void MessageGenerator::
 438GenerateClassDefinition(io::Printer* printer) {
 439  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 440    nested_generators_[i]->GenerateClassDefinition(printer);
 441    printer->Print("\n");
 442    printer->Print(kThinSeparator);
 443    printer->Print("\n");
 444  }
 445
 446  map<string, string> vars;
 447  vars["classname"] = classname_;
 448  vars["field_count"] = SimpleItoa(descriptor_->field_count());
 449  if (dllexport_decl_.empty()) {
 450    vars["dllexport"] = "";
 451  } else {
 452    vars["dllexport"] = dllexport_decl_ + " ";
 453  }
 454  vars["superclass"] = SuperClassName(descriptor_);
 455
 456  printer->Print(vars,
 457    "class $dllexport$$classname$ : public $superclass$ {\n"
 458    " public:\n");
 459  printer->Indent();
 460
 461  printer->Print(vars,
 462    "$classname$();\n"
 463    "virtual ~$classname$();\n"
 464    "\n"
 465    "$classname$(const $classname$& from);\n"
 466    "\n"
 467    "inline $classname$& operator=(const $classname$& from) {\n"
 468    "  CopyFrom(from);\n"
 469    "  return *this;\n"
 470    "}\n"
 471    "\n");
 472
 473  if (HasUnknownFields(descriptor_->file())) {
 474    printer->Print(
 475      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
 476      "  return _unknown_fields_;\n"
 477      "}\n"
 478      "\n"
 479      "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
 480      "  return &_unknown_fields_;\n"
 481      "}\n"
 482      "\n");
 483  }
 484
 485  // Only generate this member if it's not disabled.
 486  if (HasDescriptorMethods(descriptor_->file()) &&
 487      !descriptor_->options().no_standard_descriptor_accessor()) {
 488    printer->Print(vars,
 489      "static const ::google::protobuf::Descriptor* descriptor();\n");
 490  }
 491
 492  printer->Print(vars,
 493    "static const $classname$& default_instance();\n"
 494    "\n");
 495
 496
 497  printer->Print(vars,
 498    "void Swap($classname$* other);\n"
 499    "\n"
 500    "// implements Message ----------------------------------------------\n"
 501    "\n"
 502    "$classname$* New() const;\n");
 503
 504  if (HasGeneratedMethods(descriptor_->file())) {
 505    if (HasDescriptorMethods(descriptor_->file())) {
 506      printer->Print(vars,
 507        "void CopyFrom(const ::google::protobuf::Message& from);\n"
 508        "void MergeFrom(const ::google::protobuf::Message& from);\n");
 509    } else {
 510      printer->Print(vars,
 511        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
 512    }
 513
 514    printer->Print(vars,
 515      "void CopyFrom(const $classname$& from);\n"
 516      "void MergeFrom(const $classname$& from);\n"
 517      "void Clear();\n"
 518      "bool IsInitialized() const;\n"
 519      "\n"
 520      "int ByteSize() const;\n"
 521      "bool MergePartialFromCodedStream(\n"
 522      "    ::google::protobuf::io::CodedInputStream* input);\n"
 523      "void SerializeWithCachedSizes(\n"
 524      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
 525    if (HasFastArraySerialization(descriptor_->file())) {
 526      printer->Print(
 527        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
 528    }
 529  }
 530
 531  printer->Print(vars,
 532    "int GetCachedSize() const { return _cached_size_; }\n"
 533    "private:\n"
 534    "void SharedCtor();\n"
 535    "void SharedDtor();\n"
 536    "void SetCachedSize(int size) const;\n"
 537    "public:\n"
 538    "\n");
 539
 540  if (HasDescriptorMethods(descriptor_->file())) {
 541    printer->Print(
 542      "::google::protobuf::Metadata GetMetadata() const;\n"
 543      "\n");
 544  } else {
 545    printer->Print(
 546      "::std::string GetTypeName() const;\n"
 547      "\n");
 548  }
 549
 550  printer->Print(
 551    "// nested types ----------------------------------------------------\n"
 552    "\n");
 553
 554  // Import all nested message classes into this class's scope with typedefs.
 555  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 556    const Descriptor* nested_type = descriptor_->nested_type(i);
 557    printer->Print("typedef $nested_full_name$ $nested_name$;\n",
 558                   "nested_name", nested_type->name(),
 559                   "nested_full_name", ClassName(nested_type, false));
 560  }
 561
 562  if (descriptor_->nested_type_count() > 0) {
 563    printer->Print("\n");
 564  }
 565
 566  // Import all nested enums and their values into this class's scope with
 567  // typedefs and constants.
 568  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 569    enum_generators_[i]->GenerateSymbolImports(printer);
 570    printer->Print("\n");
 571  }
 572
 573  printer->Print(
 574    "// accessors -------------------------------------------------------\n"
 575    "\n");
 576
 577  // Generate accessor methods for all fields.
 578  GenerateFieldAccessorDeclarations(printer);
 579
 580  // Declare extension identifiers.
 581  for (int i = 0; i < descriptor_->extension_count(); i++) {
 582    extension_generators_[i]->GenerateDeclaration(printer);
 583  }
 584
 585
 586  printer->Print(
 587    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
 588    "full_name", descriptor_->full_name());
 589
 590  // Generate private members.
 591  printer->Outdent();
 592  printer->Print(" private:\n");
 593  printer->Indent();
 594
 595  for (int i = 0; i < descriptor_->field_count(); i++) {
 596    if (!descriptor_->field(i)->is_repeated()) {
 597      printer->Print(
 598        "inline void set_has_$name$();\n",
 599        "name", FieldName(descriptor_->field(i)));
 600      printer->Print(
 601        "inline void clear_has_$name$();\n",
 602        "name", FieldName(descriptor_->field(i)));
 603    }
 604  }
 605  printer->Print("\n");
 606
 607  // To minimize padding, data members are divided into three sections:
 608  // (1) members assumed to align to 8 bytes
 609  // (2) members corresponding to message fields, re-ordered to optimize
 610  //     alignment.
 611  // (3) members assumed to align to 4 bytes.
 612
 613  // Members assumed to align to 8 bytes:
 614
 615  if (descriptor_->extension_range_count() > 0) {
 616    printer->Print(
 617      "::google::protobuf::internal::ExtensionSet _extensions_;\n"
 618      "\n");
 619  }
 620
 621  if (HasUnknownFields(descriptor_->file())) {
 622    printer->Print(
 623      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
 624      "\n");
 625  }
 626
 627  // Field members:
 628
 629  vector<const FieldDescriptor*> fields;
 630  for (int i = 0; i < descriptor_->field_count(); i++) {
 631    fields.push_back(descriptor_->field(i));
 632  }
 633  OptimizePadding(&fields);
 634  for (int i = 0; i < fields.size(); ++i) {
 635    field_generators_.get(fields[i]).GeneratePrivateMembers(printer);
 636  }
 637
 638  // Members assumed to align to 4 bytes:
 639
 640  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
 641  printer->Print(
 642      "\n"
 643      "mutable int _cached_size_;\n");
 644
 645  // Generate _has_bits_.
 646  if (descriptor_->field_count() > 0) {
 647    printer->Print(vars,
 648      "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n"
 649      "\n");
 650  } else {
 651    // Zero-size arrays aren't technically allowed, and MSVC in particular
 652    // doesn't like them.  We still need to declare these arrays to make
 653    // other code compile.  Since this is an uncommon case, we'll just declare
 654    // them with size 1 and waste some space.  Oh well.
 655    printer->Print(
 656      "::google::protobuf::uint32 _has_bits_[1];\n"
 657      "\n");
 658  }
 659
 660  // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
 661  // friends so that they can access private static variables like
 662  // default_instance_ and reflection_.
 663  printer->Print(
 664    "friend void $dllexport_decl$ $adddescriptorsname$();\n",
 665    "dllexport_decl", dllexport_decl_,
 666    "adddescriptorsname",
 667      GlobalAddDescriptorsName(descriptor_->file()->name()));
 668  printer->Print(
 669    "friend void $assigndescriptorsname$();\n"
 670    "friend void $shutdownfilename$();\n"
 671    "\n",
 672    "assigndescriptorsname",
 673      GlobalAssignDescriptorsName(descriptor_->file()->name()),
 674    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
 675
 676  printer->Print(
 677    "void InitAsDefaultInstance();\n"
 678    "static $classname$* default_instance_;\n",
 679    "classname", classname_);
 680
 681  printer->Outdent();
 682  printer->Print(vars, "};");
 683}
 684
 685void MessageGenerator::
 686GenerateInlineMethods(io::Printer* printer) {
 687  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 688    nested_generators_[i]->GenerateInlineMethods(printer);
 689    printer->Print(kThinSeparator);
 690    printer->Print("\n");
 691  }
 692
 693  GenerateFieldAccessorDefinitions(printer);
 694}
 695
 696void MessageGenerator::
 697GenerateDescriptorDeclarations(io::Printer* printer) {
 698  printer->Print(
 699    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
 700    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
 701    "  $name$_reflection_ = NULL;\n",
 702    "name", classname_);
 703
 704  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 705    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
 706  }
 707
 708  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 709    printer->Print(
 710      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
 711      "name", ClassName(descriptor_->enum_type(i), false));
 712  }
 713}
 714
 715void MessageGenerator::
 716GenerateDescriptorInitializer(io::Printer* printer, int index) {
 717  // TODO(kenton):  Passing the index to this method is redundant; just use
 718  //   descriptor_->index() instead.
 719  map<string, string> vars;
 720  vars["classname"] = classname_;
 721  vars["index"] = SimpleItoa(index);
 722
 723  // Obtain the descriptor from the parent's descriptor.
 724  if (descriptor_->containing_type() == NULL) {
 725    printer->Print(vars,
 726      "$classname$_descriptor_ = file->message_type($index$);\n");
 727  } else {
 728    vars["parent"] = ClassName(descriptor_->containing_type(), false);
 729    printer->Print(vars,
 730      "$classname$_descriptor_ = "
 731        "$parent$_descriptor_->nested_type($index$);\n");
 732  }
 733
 734  // Generate the offsets.
 735  GenerateOffsets(printer);
 736
 737  // Construct the reflection object.
 738  printer->Print(vars,
 739    "$classname$_reflection_ =\n"
 740    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
 741    "    $classname$_descriptor_,\n"
 742    "    $classname$::default_instance_,\n"
 743    "    $classname$_offsets_,\n"
 744    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
 745    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
 746      "$classname$, _unknown_fields_),\n");
 747  if (descriptor_->extension_range_count() > 0) {
 748    printer->Print(vars,
 749      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
 750        "$classname$, _extensions_),\n");
 751  } else {
 752    // No extensions.
 753    printer->Print(vars,
 754      "    -1,\n");
 755  }
 756  printer->Print(vars,
 757    "    ::google::protobuf::DescriptorPool::generated_pool(),\n"
 758    "    ::google::protobuf::MessageFactory::generated_factory(),\n"
 759    "    sizeof($classname$));\n");
 760
 761  // Handle nested types.
 762  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 763    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
 764  }
 765
 766  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 767    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
 768  }
 769}
 770
 771void MessageGenerator::
 772GenerateTypeRegistrations(io::Printer* printer) {
 773  // Register this message type with the message factory.
 774  printer->Print(
 775    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
 776    "  $classname$_descriptor_, &$classname$::default_instance());\n",
 777    "classname", classname_);
 778
 779  // Handle nested types.
 780  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 781    nested_generators_[i]->GenerateTypeRegistrations(printer);
 782  }
 783}
 784
 785void MessageGenerator::
 786GenerateDefaultInstanceAllocator(io::Printer* printer) {
 787  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
 788  // because we need to make sure all default instances that this one might
 789  // depend on are constructed first.
 790  printer->Print(
 791    "$classname$::default_instance_ = new $classname$();\n",
 792    "classname", classname_);
 793
 794  // Handle nested types.
 795  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 796    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
 797  }
 798
 799}
 800
 801void MessageGenerator::
 802GenerateDefaultInstanceInitializer(io::Printer* printer) {
 803  printer->Print(
 804    "$classname$::default_instance_->InitAsDefaultInstance();\n",
 805    "classname", classname_);
 806
 807  // Register extensions.
 808  for (int i = 0; i < descriptor_->extension_count(); i++) {
 809    extension_generators_[i]->GenerateRegistration(printer);
 810  }
 811
 812  // Handle nested types.
 813  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 814    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
 815  }
 816}
 817
 818void MessageGenerator::
 819GenerateShutdownCode(io::Printer* printer) {
 820  printer->Print(
 821    "delete $classname$::default_instance_;\n",
 822    "classname", classname_);
 823
 824  if (HasDescriptorMethods(descriptor_->file())) {
 825    printer->Print(
 826      "delete $classname$_reflection_;\n",
 827      "classname", classname_);
 828  }
 829
 830  // Handle nested types.
 831  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 832    nested_generators_[i]->GenerateShutdownCode(printer);
 833  }
 834}
 835
 836void MessageGenerator::
 837GenerateClassMethods(io::Printer* printer) {
 838  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 839    enum_generators_[i]->GenerateMethods(printer);
 840  }
 841
 842  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 843    nested_generators_[i]->GenerateClassMethods(printer);
 844    printer->Print("\n");
 845    printer->Print(kThinSeparator);
 846    printer->Print("\n");
 847  }
 848
 849  // Generate non-inline field definitions.
 850  for (int i = 0; i < descriptor_->field_count(); i++) {
 851    field_generators_.get(descriptor_->field(i))
 852                     .GenerateNonInlineAccessorDefinitions(printer);
 853  }
 854
 855  // Generate field number constants.
 856  printer->Print("#ifndef _MSC_VER\n");
 857  for (int i = 0; i < descriptor_->field_count(); i++) {
 858    const FieldDescriptor *field = descriptor_->field(i);
 859    printer->Print(
 860      "const int $classname$::$constant_name$;\n",
 861      "classname", ClassName(FieldScope(field), false),
 862      "constant_name", FieldConstantName(field));
 863  }
 864  printer->Print(
 865    "#endif  // !_MSC_VER\n"
 866    "\n");
 867
 868  // Define extension identifiers.
 869  for (int i = 0; i < descriptor_->extension_count(); i++) {
 870    extension_generators_[i]->GenerateDefinition(printer);
 871  }
 872
 873  GenerateStructors(printer);
 874  printer->Print("\n");
 875
 876  if (HasGeneratedMethods(descriptor_->file())) {
 877    GenerateClear(printer);
 878    printer->Print("\n");
 879
 880    GenerateMergeFromCodedStream(printer);
 881    printer->Print("\n");
 882
 883    GenerateSerializeWithCachedSizes(printer);
 884    printer->Print("\n");
 885
 886    if (HasFastArraySerialization(descriptor_->file())) {
 887      GenerateSerializeWithCachedSizesToArray(printer);
 888      printer->Print("\n");
 889    }
 890
 891    GenerateByteSize(printer);
 892    printer->Print("\n");
 893
 894    GenerateMergeFrom(printer);
 895    printer->Print("\n");
 896
 897    GenerateCopyFrom(printer);
 898    printer->Print("\n");
 899
 900    GenerateIsInitialized(printer);
 901    printer->Print("\n");
 902  }
 903
 904  GenerateSwap(printer);
 905  printer->Print("\n");
 906
 907  if (HasDescriptorMethods(descriptor_->file())) {
 908    printer->Print(
 909      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
 910      "  protobuf_AssignDescriptorsOnce();\n"
 911      "  ::google::protobuf::Metadata metadata;\n"
 912      "  metadata.descriptor = $classname$_descriptor_;\n"
 913      "  metadata.reflection = $classname$_reflection_;\n"
 914      "  return metadata;\n"
 915      "}\n"
 916      "\n",
 917      "classname", classname_);
 918  } else {
 919    printer->Print(
 920      "::std::string $classname$::GetTypeName() const {\n"
 921      "  return \"$type_name$\";\n"
 922      "}\n"
 923      "\n",
 924      "classname", classname_,
 925      "type_name", descriptor_->full_name());
 926  }
 927
 928}
 929
 930void MessageGenerator::
 931GenerateOffsets(io::Printer* printer) {
 932  printer->Print(
 933    "static const int $classname$_offsets_[$field_count$] = {\n",
 934    "classname", classname_,
 935    "field_count", SimpleItoa(max(1, descriptor_->field_count())));
 936  printer->Indent();
 937
 938  for (int i = 0; i < descriptor_->field_count(); i++) {
 939    const FieldDescriptor* field = descriptor_->field(i);
 940    printer->Print(
 941      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
 942      "classname", classname_,
 943      "name", FieldName(field));
 944  }
 945
 946  printer->Outdent();
 947  printer->Print("};\n");
 948}
 949
 950void MessageGenerator::
 951GenerateSharedConstructorCode(io::Printer* printer) {
 952  printer->Print(
 953    "void $classname$::SharedCtor() {\n",
 954    "classname", classname_);
 955  printer->Indent();
 956
 957  printer->Print(
 958    "_cached_size_ = 0;\n");
 959
 960  for (int i = 0; i < descriptor_->field_count(); i++) {
 961    field_generators_.get(descriptor_->field(i))
 962                     .GenerateConstructorCode(printer);
 963  }
 964
 965  printer->Print(
 966    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
 967
 968  printer->Outdent();
 969  printer->Print("}\n\n");
 970}
 971
 972void MessageGenerator::
 973GenerateSharedDestructorCode(io::Printer* printer) {
 974  printer->Print(
 975    "void $classname$::SharedDtor() {\n",
 976    "classname", classname_);
 977  printer->Indent();
 978  // Write the destructors for each field.
 979  for (int i = 0; i < descriptor_->field_count(); i++) {
 980    field_generators_.get(descriptor_->field(i))
 981                     .GenerateDestructorCode(printer);
 982  }
 983
 984  printer->Print(
 985    "if (this != default_instance_) {\n");
 986
 987  // We need to delete all embedded messages.
 988  // TODO(kenton):  If we make unset messages point at default instances
 989  //   instead of NULL, then it would make sense to move this code into
 990  //   MessageFieldGenerator::GenerateDestructorCode().
 991  for (int i = 0; i < descriptor_->field_count(); i++) {
 992    const FieldDescriptor* field = descriptor_->field(i);
 993
 994    if (!field->is_repeated() &&
 995        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 996      printer->Print("  delete $name$_;\n",
 997                     "name", FieldName(field));
 998    }
 999  }
1000
1001  printer->Outdent();
1002  printer->Print(
1003    "  }\n"
1004    "}\n"
1005    "\n");
1006}
1007
1008void MessageGenerator::
1009GenerateStructors(io::Printer* printer) {
1010  string superclass = SuperClassName(descriptor_);
1011
1012  // Generate the default constructor.
1013  printer->Print(
1014    "$classname$::$classname$()\n"
1015    "  : $superclass$() {\n"
1016    "  SharedCtor();\n"
1017    "}\n",
1018    "classname", classname_,
1019    "superclass", superclass);
1020
1021  printer->Print(
1022    "\n"
1023    "void $classname$::InitAsDefaultInstance() {\n",
1024    "classname", classname_);
1025
1026  // The default instance needs all of its embedded message pointers
1027  // cross-linked to other default instances.  We can't do this initialization
1028  // in the constructor because some other default instances may not have been
1029  // constructed yet at that time.
1030  // TODO(kenton):  Maybe all message fields (even for non-default messages)
1031  //   should be initialized to point at default instances rather than NULL?
1032  for (int i = 0; i < descriptor_->field_count(); i++) {
1033    const FieldDescriptor* field = descriptor_->field(i);
1034
1035    if (!field->is_repeated() &&
1036        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1037      printer->Print(
1038          "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
1039          "name", FieldName(field),
1040          "type", FieldMessageTypeName(field));
1041    }
1042  }
1043  printer->Print(
1044    "}\n"
1045    "\n");
1046
1047  // Generate the copy constructor.
1048  printer->Print(
1049    "$classname$::$classname$(const $classname$& from)\n"
1050    "  : $superclass$() {\n"
1051    "  SharedCtor();\n"
1052    "  MergeFrom(from);\n"
1053    "}\n"
1054    "\n",
1055    "classname", classname_,
1056    "superclass", superclass);
1057
1058  // Generate the shared constructor code.
1059  GenerateSharedConstructorCode(printer);
1060
1061  // Generate the destructor.
1062  printer->Print(
1063    "$classname$::~$classname$() {\n"
1064    "  SharedDtor();\n"
1065    "}\n"
1066    "\n",
1067    "classname", classname_);
1068
1069  // Generate the shared destructor code.
1070  GenerateSharedDestructorCode(printer);
1071
1072  // Generate SetCachedSize.
1073  printer->Print(
1074    "void $classname$::SetCachedSize(int size) const {\n"
1075    "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1076    "  _cached_size_ = size;\n"
1077    "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1078    "}\n",
1079    "classname", classname_);
1080
1081  // Only generate this member if it's not disabled.
1082  if (HasDescriptorMethods(descriptor_->file()) &&
1083      !descriptor_->options().no_standard_descriptor_accessor()) {
1084    printer->Print(
1085      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
1086      "  protobuf_AssignDescriptorsOnce();\n"
1087      "  return $classname$_descriptor_;\n"
1088      "}\n"
1089      "\n",
1090      "classname", classname_,
1091      "adddescriptorsname",
1092      GlobalAddDescriptorsName(descriptor_->file()->name()));
1093  }
1094
1095  printer->Print(
1096    "const $classname$& $classname$::default_instance() {\n"
1097    "  if (default_instance_ == NULL) $adddescriptorsname$();"
1098    "  return *default_instance_;\n"
1099    "}\n"
1100    "\n"
1101    "$classname$* $classname$::default_instance_ = NULL;\n"
1102    "\n"
1103    "$classname$* $classname$::New() const {\n"
1104    "  return new $classname$;\n"
1105    "}\n",
1106    "classname", classname_,
1107    "adddescriptorsname",
1108    GlobalAddDescriptorsName(descriptor_->file()->name()));
1109
1110}
1111
1112void MessageGenerator::
1113GenerateClear(io::Printer* printer) {
1114  printer->Print("void $classname$::Clear() {\n",
1115                 "classname", classname_);
1116  printer->Indent();
1117
1118  int last_index = -1;
1119
1120  if (descriptor_->extension_range_count() > 0) {
1121    printer->Print("_extensions_.Clear();\n");
1122  }
1123
1124  for (int i = 0; i < descriptor_->field_count(); i++) {
1125    const FieldDescriptor* field = descriptor_->field(i);
1126
1127    if (!field->is_repeated()) {
1128      // We can use the fact that _has_bits_ is a giant bitfield to our
1129      // advantage:  We can check up to 32 bits at a time for equality to
1130      // zero, and skip the whole range if so.  This can improve the speed
1131      // of Clear() for messages which contain a very large number of
1132      // optional fields of which only a few are used at a time.  Here,
1133      // we've chosen to check 8 bits at a time rather than 32.
1134      if (i / 8 != last_index / 8 || last_index < 0) {
1135        if (last_index >= 0) {
1136          printer->Outdent();
1137          printer->Print("}\n");
1138        }
1139        printer->Print(
1140          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1141          "index", SimpleItoa(field->index()));
1142        printer->Indent();
1143      }
1144      last_index = i;
1145
1146      // It's faster to just overwrite primitive types, but we should
1147      // only clear strings and messages if they were set.
1148      // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
1149      bool should_check_bit =
1150        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1151        field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
1152
1153      if (should_check_bit) {
1154        printer->Print(
1155          "if (has_$name$()) {\n",
1156          "name", FieldName(field));
1157        printer->Indent();
1158      }
1159
1160      field_generators_.get(field).GenerateClearingCode(printer);
1161
1162      if (should_check_bit) {
1163        printer->Outdent();
1164        printer->Print("}\n");
1165      }
1166    }
1167  }
1168
1169  if (last_index >= 0) {
1170    printer->Outdent();
1171    printer->Print("}\n");
1172  }
1173
1174  // Repeated fields don't use _has_bits_ so we clear them in a separate
1175  // pass.
1176  for (int i = 0; i < descriptor_->field_count(); i++) {
1177    const FieldDescriptor* field = descriptor_->field(i);
1178
1179    if (field->is_repeated()) {
1180      field_generators_.get(field).GenerateClearingCode(printer);
1181    }
1182  }
1183
1184  printer->Print(
1185    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1186
1187  if (HasUnknownFields(descriptor_->file())) {
1188    printer->Print(
1189      "mutable_unknown_fields()->Clear();\n");
1190  }
1191
1192  printer->Outdent();
1193  printer->Print("}\n");
1194}
1195
1196void MessageGenerator::
1197GenerateSwap(io::Printer* printer) {
1198  // Generate the Swap member function.
1199  printer->Print("void $classname$::Swap($classname$* other) {\n",
1200                 "classname", classname_);
1201  printer->Indent();
1202  printer->Print("if (other != this) {\n");
1203  printer->Indent();
1204
1205  if (HasGeneratedMethods(descriptor_->file())) {
1206    for (int i = 0; i < descriptor_->field_count(); i++) {
1207      const FieldDescriptor* field = descriptor_->field(i);
1208      field_generators_.get(field).GenerateSwappingCode(printer);
1209    }
1210
1211    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1212      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1213                     "i", SimpleItoa(i));
1214    }
1215
1216    if (HasUnknownFields(descriptor_->file())) {
1217      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
1218    }
1219    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1220    if (descriptor_->extension_range_count() > 0) {
1221      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
1222    }
1223  } else {
1224    printer->Print("GetReflection()->Swap(this, other);");
1225  }
1226
1227  printer->Outdent();
1228  printer->Print("}\n");
1229  printer->Outdent();
1230  printer->Print("}\n");
1231}
1232
1233void MessageGenerator::
1234GenerateMergeFrom(io::Printer* printer) {
1235  if (HasDescriptorMethods(descriptor_->file())) {
1236    // Generate the generalized MergeFrom (aka that which takes in the Message
1237    // base class as a parameter).
1238    printer->Print(
1239      "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
1240      "  GOOGLE_CHECK_NE(&from, this);\n",
1241      "classname", classname_);
1242    printer->Indent();
1243
1244    // Cast the message to the proper type. If we find that the message is
1245    // *not* of the proper type, we can still call Merge via the reflection
1246    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1247    // for each message.
1248    printer->Print(
1249      "const $classname$* source =\n"
1250      "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1251      "    &from);\n"
1252      "if (source == NULL) {\n"
1253      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1254      "} else {\n"
1255      "  MergeFrom(*source);\n"
1256      "}\n",
1257      "classname", classname_);
1258
1259    printer->Outdent();
1260    printer->Print("}\n\n");
1261  } else {
1262    // Generate CheckTypeAndMergeFrom().
1263    printer->Print(
1264      "void $classname$::CheckTypeAndMergeFrom(\n"
1265      "    const ::google::protobuf::MessageLite& from) {\n"
1266      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
1267      "}\n"
1268      "\n",
1269      "classname", classname_);
1270  }
1271
1272  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1273  printer->Print(
1274    "void $classname$::MergeFrom(const $classname$& from) {\n"
1275    "  GOOGLE_CHECK_NE(&from, this);\n",
1276    "classname", classname_);
1277  printer->Indent();
1278
1279  // Merge Repeated fields. These fields do not require a
1280  // check as we can simply iterate over them.
1281  for (int i = 0; i < descriptor_->field_count(); ++i) {
1282    const FieldDescriptor* field = descriptor_->field(i);
1283
1284    if (field->is_repeated()) {
1285      field_generators_.get(field).GenerateMergingCode(printer);
1286    }
1287  }
1288
1289  // Merge Optional and Required fields (after a _has_bit check).
1290  int last_index = -1;
1291
1292  for (int i = 0; i < descriptor_->field_count(); ++i) {
1293    const FieldDescriptor* field = descriptor_->field(i);
1294
1295    if (!field->is_repeated()) {
1296      // See above in GenerateClear for an explanation of this.
1297      if (i / 8 != last_index / 8 || last_index < 0) {
1298        if (last_index >= 0) {
1299          printer->Outdent();
1300          printer->Print("}\n");
1301        }
1302        printer->Print(
1303          "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1304          "index", SimpleItoa(field->index()));
1305        printer->Indent();
1306      }
1307
1308      last_index = i;
1309
1310      printer->Print(
1311        "if (from.has_$name$()) {\n",
1312        "name", FieldName(field));
1313      printer->Indent();
1314
1315      field_generators_.get(field).GenerateMergingCode(printer);
1316
1317      printer->Outdent();
1318      printer->Print("}\n");
1319    }
1320  }
1321
1322  if (last_index >= 0) {
1323    printer->Outdent();
1324    printer->Print("}\n");
1325  }
1326
1327  if (descriptor_->extension_range_count() > 0) {
1328    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1329  }
1330
1331  if (HasUnknownFields(descriptor_->file())) {
1332    printer->Print(
1333      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
1334  }
1335
1336  printer->Outdent();
1337  printer->Print("}\n");
1338}
1339
1340void MessageGenerator::
1341GenerateCopyFrom(io::Printer* printer) {
1342  if (HasDescriptorMethods(descriptor_->file())) {
1343    // Generate the generalized CopyFrom (aka that which takes in the Message
1344    // base class as a parameter).
1345    printer->Print(
1346      "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1347      "classname", classname_);
1348    printer->Indent();
1349
1350    printer->Print(
1351      "if (&from == this) return;\n"
1352      "Clear();\n"
1353      "MergeFrom(from);\n");
1354
1355    printer->Outdent();
1356    printer->Print("}\n\n");
1357  }
1358
1359  // Generate the class-specific CopyFrom.
1360  printer->Print(
1361    "void $classname$::CopyFrom(const $classname$& from) {\n",
1362    "classname", classname_);
1363  printer->Indent();
1364
1365  printer->Print(
1366    "if (&from == this) return;\n"
1367    "Clear();\n"
1368    "MergeFrom(from);\n");
1369
1370  printer->Outdent();
1371  printer->Print("}\n");
1372}
1373
1374void MessageGenerator::
1375GenerateMergeFromCodedStream(io::Printer* printer) {
1376  if (descriptor_->options().message_set_wire_format()) {
1377    // Special-case MessageSet.
1378    printer->Print(
1379      "bool $classname$::MergePartialFromCodedStream(\n"
1380      "    ::google::protobuf::io::CodedInputStream* input) {\n"
1381      "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
1382      "                                      mutable_unknown_fields());\n"
1383      "}\n",
1384      "classname", classname_);
1385    return;
1386  }
1387
1388  printer->Print(
1389    "bool $classname$::MergePartialFromCodedStream(\n"
1390    "    ::google::protobuf::io::CodedInputStream* input) {\n"
1391    "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
1392    "  ::google::protobuf::uint32 tag;\n"
1393    "  while ((tag = input->ReadTag()) != 0) {\n",
1394    "classname", classname_);
1395
1396  printer->Indent();
1397  printer->Indent();
1398
1399  if (descriptor_->field_count() > 0) {
1400    // We don't even want to print the switch() if we have no fields because
1401    // MSVC dislikes switch() statements that contain only a default value.
1402
1403    // Note:  If we just switched on the tag rather than the field number, we
1404    // could avoid the need for the if() to check the wire type at the beginning
1405    // of each case.  However, this is actually a bit slower in practice as it
1406    // creates a jump table that is 8x larger and sparser, and meanwhile the
1407    // if()s are highly predictable.
1408    printer->Print(
1409      "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
1410
1411    printer->Indent();
1412
1413    scoped_array<const FieldDescriptor*> ordered_fields(
1414      SortFieldsByNumber(descriptor_));
1415
1416    for (int i = 0; i < descriptor_->field_count(); i++) {
1417      const FieldDescriptor* field = ordered_fields[i];
1418
1419      PrintFieldComment(printer, field);
1420
1421      printer->Print(
1422        "case $number$: {\n",
1423        "number", SimpleItoa(field->number()));
1424      printer->Indent();
1425      const FieldGenerator& field_generator = field_generators_.get(field);
1426
1427      // Emit code to parse the common, expected case.
1428      printer->Print(
1429        "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1430        "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
1431        "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
1432
1433      if (i > 0 || (field->is_repeated() && !field->options().packed())) {
1434        printer->Print(
1435          " parse_$name$:\n",
1436          "name", field->name());
1437      }
1438
1439      printer->Indent();
1440      if (field->options().packed()) {
1441        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1442      } else {
1443        field_generator.GenerateMergeFromCodedStream(printer);
1444      }
1445      printer->Outdent();
1446
1447      // Emit code to parse unexpectedly packed or unpacked values.
1448      if (field->is_packable() && field->options().packed()) {
1449        printer->Print(
1450          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1451          "           == ::google::protobuf::internal::WireFormatLite::\n"
1452          "              WIRETYPE_$wiretype$) {\n",
1453          "wiretype",
1454          kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
1455        printer->Indent();
1456        field_generator.GenerateMergeFromCodedStream(printer);
1457        printer->Outdent();
1458      } else if (field->is_packable() && !field->options().packed()) {
1459        printer->Print(
1460          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1461          "           == ::google::protobuf::internal::WireFormatLite::\n"
1462          "              WIRETYPE_LENGTH_DELIMITED) {\n");
1463        printer->Indent();
1464        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1465        printer->Outdent();
1466      }
1467
1468      printer->Print(
1469        "} else {\n"
1470        "  goto handle_uninterpreted;\n"
1471        "}\n");
1472
1473      // switch() is slow since it can't be predicted well.  Insert some if()s
1474      // here that attempt to predict the next tag.
1475      if (field->is_repeated() && !field->options().packed()) {
1476        // Expect repeats of this field.
1477        printer->Print(
1478          "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
1479          "tag", SimpleItoa(WireFormat::MakeTag(field)),
1480          "name", field->name());
1481      }
1482
1483      if (i + 1 < descriptor_->field_count()) {
1484        // Expect the next field in order.
1485        const FieldDescriptor* next_field = ordered_fields[i + 1];
1486        printer->Print(
1487          "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
1488          "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
1489          "next_name", next_field->name());
1490      } else {
1491        // Expect EOF.
1492        // TODO(kenton):  Expect group end-tag?
1493        printer->Print(
1494          "if (input->ExpectAtEnd()) return true;\n");
1495      }
1496
1497      printer->Print(
1498        "break;\n");
1499
1500      printer->Outdent();
1501      printer->Print("}\n\n");
1502    }
1503
1504    printer->Print(
1505      "default: {\n"
1506      "handle_uninterpreted:\n");
1507    printer->Indent();
1508  }
1509
1510  // Is this an end-group tag?  If so, this must be the end of the message.
1511  printer->Print(
1512    "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1513    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1514    "  return true;\n"
1515    "}\n");
1516
1517  // Handle extensi…

Large files files are truncated, but you can click here to view the full file