// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <map>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <utility>
#include <vector>
#include <google/protobuf/compiler/cpp/cpp_message.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_enum.h>
#include <google/protobuf/compiler/cpp/cpp_extension.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h>


namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {

using internal::WireFormat;
using internal::WireFormatLite;

namespace {

template <class T>
void PrintFieldComment(io::Printer* printer, const T* field) {
  // Print the field's (or oneof's) proto-syntax definition as a comment.
  // We don't want to print group bodies so we cut off after the first
  // line.
  DebugStringOptions options;
  options.elide_group_body = true;
  options.elide_oneof_body = true;
  string def = field->DebugStringWithOptions(options);
  printer->Print("// $def$\n",
    "def", def.substr(0, def.find_first_of('\n')));
}

struct FieldOrderingByNumber {
  inline bool operator()(const FieldDescriptor* a,
                         const FieldDescriptor* b) const {
    return a->number() < b->number();
  }
};

// Sort the fields of the given Descriptor by number into a new[]'d array
// and return it.
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
  const FieldDescriptor** fields =
    new const FieldDescriptor*[descriptor->field_count()];
  for (int i = 0; i < descriptor->field_count(); i++) {
    fields[i] = descriptor->field(i);
  }
  std::sort(fields, fields + descriptor->field_count(),
            FieldOrderingByNumber());
  return fields;
}

// Functor for sorting extension ranges by their "start" field number.
struct ExtensionRangeSorter {
  bool operator()(const Descriptor::ExtensionRange* left,
                  const Descriptor::ExtensionRange* right) const {
    return left->start < right->start;
  }
};

// Returns true if the "required" restriction check should be ignored for the
// given field.
inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
                                                  const Options& options) {
  return false;
}

// Returns true if the message type has any required fields.  If it doesn't,
// we can optimize out calls to its IsInitialized() method.
//
// already_seen is used to avoid checking the same type multiple times
// (and also to protect against recursion).
static bool HasRequiredFields(const Descriptor* type, const Options& options,
                              hash_set<const Descriptor*>* already_seen) {
  if (already_seen->count(type) > 0) {
    // Since the first occurrence of a required field causes the whole
    // function to return true, we can assume that if the type is already
    // in the cache it didn't have any required fields.
    return false;
  }
  already_seen->insert(type);

  // If the type has extensions, an extension with message type could contain
  // required fields, so we have to be conservative and assume such an
  // extension exists.
  if (type->extension_range_count() > 0) return true;

  for (int i = 0; i < type->field_count(); i++) {
    const FieldDescriptor* field = type->field(i);
    if (field->is_required()) {
      return true;
    }
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
        !ShouldIgnoreRequiredFieldCheck(field, options)) {
      if (HasRequiredFields(field->message_type(), options, already_seen)) {
        return true;
      }
    }
  }

  return false;
}

static bool HasRequiredFields(const Descriptor* type, const Options& options) {
  hash_set<const Descriptor*> already_seen;
  return HasRequiredFields(type, options, &already_seen);
}

// This returns an estimate of the compiler's alignment for the field.  This
// can't guarantee to be correct because the generated code could be compiled on
// different systems with different alignment rules.  The estimates below assume
// 64-bit pointers.
int EstimateAlignmentSize(const FieldDescriptor* field) {
  if (field == NULL) return 0;
  if (field->is_repeated()) return 8;
  switch (field->cpp_type()) {
    case FieldDescriptor::CPPTYPE_BOOL:
      return 1;

    case FieldDescriptor::CPPTYPE_INT32:
    case FieldDescriptor::CPPTYPE_UINT32:
    case FieldDescriptor::CPPTYPE_ENUM:
    case FieldDescriptor::CPPTYPE_FLOAT:
      return 4;

    case FieldDescriptor::CPPTYPE_INT64:
    case FieldDescriptor::CPPTYPE_UINT64:
    case FieldDescriptor::CPPTYPE_DOUBLE:
    case FieldDescriptor::CPPTYPE_STRING:
    case FieldDescriptor::CPPTYPE_MESSAGE:
      return 8;
  }
  GOOGLE_LOG(FATAL) << "Can't get here.";
  return -1;  // Make compiler happy.
}

// FieldGroup is just a helper for OptimizePadding below.  It holds a vector of
// fields that are grouped together because they have compatible alignment, and
// a preferred location in the final field ordering.
class FieldGroup {
 public:
  FieldGroup()
      : preferred_location_(0) {}

  // A group with a single field.
  FieldGroup(float preferred_location, const FieldDescriptor* field)
      : preferred_location_(preferred_location),
        fields_(1, field) {}

  // Append the fields in 'other' to this group.
  void Append(const FieldGroup& other) {
    if (other.fields_.empty()) {
      return;
    }
    // Preferred location is the average among all the fields, so we weight by
    // the number of fields on each FieldGroup object.
    preferred_location_ =
        (preferred_location_ * fields_.size() +
         (other.preferred_location_ * other.fields_.size())) /
        (fields_.size() + other.fields_.size());
    fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
  }

  void SetPreferredLocation(float location) { preferred_location_ = location; }
  const vector<const FieldDescriptor*>& fields() const { return fields_; }

  // FieldGroup objects sort by their preferred location.
  bool operator<(const FieldGroup& other) const {
    return preferred_location_ < other.preferred_location_;
  }

 private:
  // "preferred_location_" is an estimate of where this group should go in the
  // final list of fields.  We compute this by taking the average index of each
  // field in this group in the original ordering of fields.  This is very
  // approximate, but should put this group close to where its member fields
  // originally went.
  float preferred_location_;
  vector<const FieldDescriptor*> fields_;
  // We rely on the default copy constructor and operator= so this type can be
  // used in a vector.
};

// Reorder 'fields' so that if the fields are output into a c++ class in the new
// order, the alignment padding is minimized.  We try to do this while keeping
// each field as close as possible to its original position so that we don't
// reduce cache locality much for function that access each field in order.
void OptimizePadding(vector<const FieldDescriptor*>* fields) {
  // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
  vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
  for (int i = 0; i < fields->size(); ++i) {
    switch (EstimateAlignmentSize((*fields)[i])) {
      case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
      case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
      case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
      default:
        GOOGLE_LOG(FATAL) << "Unknown alignment size.";
    }
  }

  // Now group fields aligned to 1 byte into sets of 4, and treat those like a
  // single field aligned to 4 bytes.
  for (int i = 0; i < aligned_to_1.size(); i += 4) {
    FieldGroup field_group;
    for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
      field_group.Append(aligned_to_1[j]);
    }
    aligned_to_4.push_back(field_group);
  }
  // Sort by preferred location to keep fields as close to their original
  // location as possible.  Using stable_sort ensures that the output is
  // consistent across runs.
  std::stable_sort(aligned_to_4.begin(), aligned_to_4.end());

  // Now group fields aligned to 4 bytes (or the 4-field groups created above)
  // into pairs, and treat those like a single field aligned to 8 bytes.
  for (int i = 0; i < aligned_to_4.size(); i += 2) {
    FieldGroup field_group;
    for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
      field_group.Append(aligned_to_4[j]);
    }
    if (i == aligned_to_4.size() - 1) {
      // Move incomplete 4-byte block to the end.
      field_group.SetPreferredLocation(fields->size() + 1);
    }
    aligned_to_8.push_back(field_group);
  }
  // Sort by preferred location.
  std::stable_sort(aligned_to_8.begin(), aligned_to_8.end());

  // Now pull out all the FieldDescriptors in order.
  fields->clear();
  for (int i = 0; i < aligned_to_8.size(); ++i) {
    fields->insert(fields->end(),
                   aligned_to_8[i].fields().begin(),
                   aligned_to_8[i].fields().end());
  }
}

string MessageTypeProtoName(const FieldDescriptor* field) {
  return field->message_type()->full_name();
}

// Emits an if-statement with a condition that evaluates to true if |field| is
// considered non-default (will be sent over the wire), for message types
// without true field presence. Should only be called if
// !HasFieldPresence(message_descriptor).
bool EmitFieldNonDefaultCondition(io::Printer* printer,
                                  const string& prefix,
                                  const FieldDescriptor* field) {
  // Merge and serialize semantics: primitive fields are merged/serialized only
  // if non-zero (numeric) or non-empty (string).
  if (!field->is_repeated() && !field->containing_oneof()) {
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
      printer->Print(
          "if ($prefix$$name$().size() > 0) {\n",
          "prefix", prefix,
          "name", FieldName(field));
    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      // Message fields still have has_$name$() methods.
      printer->Print(
          "if ($prefix$has_$name$()) {\n",
          "prefix", prefix,
          "name", FieldName(field));
    } else {
      printer->Print(
          "if ($prefix$$name$() != 0) {\n",
          "prefix", prefix,
          "name", FieldName(field));
    }
    printer->Indent();
    return true;
  } else if (field->containing_oneof()) {
    printer->Print(
        "if (has_$name$()) {\n",
        "name", FieldName(field));
    printer->Indent();
    return true;
  }
  return false;
}

// Does the given field have a has_$name$() method?
bool HasHasMethod(const FieldDescriptor* field) {
  if (HasFieldPresence(field->file())) {
    // In proto1/proto2, every field has a has_$name$() method.
    return true;
  }
  // For message types without true field presence, only fields with a message
  // type have a has_$name$() method.
  return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE;
}

// Collects map entry message type information.
void CollectMapInfo(const Descriptor* descriptor,
                    map<string, string>* variables) {
  GOOGLE_CHECK(IsMapEntryMessage(descriptor));
  const FieldDescriptor* key = descriptor->FindFieldByName("key");
  const FieldDescriptor* val = descriptor->FindFieldByName("value");
  (*variables)["key"] = PrimitiveTypeName(key->cpp_type());
  switch (val->cpp_type()) {
    case FieldDescriptor::CPPTYPE_MESSAGE:
      (*variables)["val"] = FieldMessageTypeName(val);
      break;
    case FieldDescriptor::CPPTYPE_ENUM:
      (*variables)["val"] = ClassName(val->enum_type(), true);
      break;
    default:
      (*variables)["val"] = PrimitiveTypeName(val->cpp_type());
  }
  (*variables)["key_wire_type"] =
      "::google::protobuf::internal::WireFormatLite::TYPE_" +
      ToUpper(DeclaredTypeMethodName(key->type()));
  (*variables)["val_wire_type"] =
      "::google::protobuf::internal::WireFormatLite::TYPE_" +
      ToUpper(DeclaredTypeMethodName(val->type()));
}

// Does the given field have a private (internal helper only) has_$name$()
// method?
bool HasPrivateHasMethod(const FieldDescriptor* field) {
  // Only for oneofs in message types with no field presence. has_$name$(),
  // based on the oneof case, is still useful internally for generated code.
  return (!HasFieldPresence(field->file()) &&
          field->containing_oneof() != NULL);
}

}  // anonymous namespace

// ===================================================================

MessageGenerator::MessageGenerator(const Descriptor* descriptor,
                                   const Options& options)
    : descriptor_(descriptor),
      classname_(ClassName(descriptor, false)),
      options_(options),
      field_generators_(descriptor, options),
      nested_generators_(new google::protobuf::scoped_ptr<
          MessageGenerator>[descriptor->nested_type_count()]),
      enum_generators_(
          new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
      extension_generators_(new google::protobuf::scoped_ptr<
          ExtensionGenerator>[descriptor->extension_count()]),
      use_dependent_base_(false) {

  for (int i = 0; i < descriptor->nested_type_count(); i++) {
    nested_generators_[i].reset(
      new MessageGenerator(descriptor->nested_type(i), options));
  }

  for (int i = 0; i < descriptor->enum_type_count(); i++) {
    enum_generators_[i].reset(
      new EnumGenerator(descriptor->enum_type(i), options));
  }

  for (int i = 0; i < descriptor->extension_count(); i++) {
    extension_generators_[i].reset(
      new ExtensionGenerator(descriptor->extension(i), options));
  }

  num_required_fields_ = 0;
  for (int i = 0; i < descriptor->field_count(); i++) {
    if (descriptor->field(i)->is_required()) {
      ++num_required_fields_;
    }
    if (options.proto_h && IsFieldDependent(descriptor->field(i))) {
      use_dependent_base_ = true;
    }
  }
  if (options.proto_h && descriptor->oneof_decl_count() > 0) {
    // Always make oneofs dependent.
    use_dependent_base_ = true;
  }
}

MessageGenerator::~MessageGenerator() {}

void MessageGenerator::
FillMessageForwardDeclarations(map<string, const Descriptor*>* class_names) {
  (*class_names)[classname_] = descriptor_;

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // map entry message doesn't need forward declaration. Since map entry
    // message cannot be a top level class, we just need to avoid calling
    // GenerateForwardDeclaration here.
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->FillMessageForwardDeclarations(class_names);
  }
}

void MessageGenerator::
FillEnumForwardDeclarations(map<string, const EnumDescriptor*>* enum_names) {
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->FillEnumForwardDeclarations(enum_names);
  }
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    enum_generators_[i]->FillForwardDeclaration(enum_names);
  }
}

void MessageGenerator::
GenerateEnumDefinitions(io::Printer* printer) {
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->GenerateEnumDefinitions(printer);
  }

  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    enum_generators_[i]->GenerateDefinition(printer);
  }
}

void MessageGenerator::
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
  }
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
  }
}

void MessageGenerator::
GenerateDependentFieldAccessorDeclarations(io::Printer* printer) {
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    PrintFieldComment(printer, field);

    map<string, string> vars;
    SetCommonFieldVariables(field, &vars, options_);

    if (use_dependent_base_ && IsFieldDependent(field)) {
      // If the message is dependent, the inline clear_*() method will need
      // to delete the message type, so it must be in the dependent base
      // class. (See also GenerateFieldAccessorDeclarations.)
      printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
    }
    // Generate type-specific accessor declarations.
    field_generators_.get(field).GenerateDependentAccessorDeclarations(printer);
    printer->Print("\n");
  }
}

void MessageGenerator::
GenerateFieldAccessorDeclarations(io::Printer* printer) {
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    PrintFieldComment(printer, field);

    map<string, string> vars;
    SetCommonFieldVariables(field, &vars, options_);
    vars["constant_name"] = FieldConstantName(field);

    bool dependent_field = use_dependent_base_ && IsFieldDependent(field);
    if (dependent_field &&
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
        !field->is_map()) {
      // If this field is dependent, the dependent base class determines
      // the message type from the derived class (which is a template
      // parameter). This typedef is for that:
      printer->Print(
          "private:\n"
          "typedef $field_type$ $dependent_type$;\n"
          "public:\n",
          "field_type", FieldMessageTypeName(field),
          "dependent_type", DependentTypeName(field));
    }

    if (field->is_repeated()) {
      printer->Print(vars, "$deprecated_attr$int $name$_size() const;\n");
    } else if (HasHasMethod(field)) {
      printer->Print(vars, "$deprecated_attr$bool has_$name$() const;\n");
    } else if (HasPrivateHasMethod(field)) {
      printer->Print(vars,
          "private:\n"
          "bool has_$name$() const;\n"
          "public:\n");
    }

    if (!dependent_field) {
      // If this field is dependent, then its clear_() method is in the
      // depenent base class. (See also GenerateDependentAccessorDeclarations.)
      printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
    }
    printer->Print(vars,
                   "$deprecated_attr$static const int $constant_name$ = "
                   "$number$;\n");

    // Generate type-specific accessor declarations.
    field_generators_.get(field).GenerateAccessorDeclarations(printer);

    printer->Print("\n");
  }

  if (descriptor_->extension_range_count() > 0) {
    // Generate accessors for extensions.  We just call a macro located in
    // extension_set.h since the accessors about 80 lines of static code.
    printer->Print(
      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
      "classname", classname_);
  }

  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "$camel_oneof_name$Case $oneof_name$_case() const;\n",
        "camel_oneof_name",
        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
        "oneof_name", descriptor_->oneof_decl(i)->name());
  }
}

void MessageGenerator::
GenerateDependentFieldAccessorDefinitions(io::Printer* printer) {
  if (!use_dependent_base_) return;

  printer->Print("// $classname$\n\n", "classname",
                 DependentBaseClassTemplateName(descriptor_));

  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    PrintFieldComment(printer, field);

    // These functions are not really dependent: they are part of the
    // (non-dependent) derived class. However, they need to live outside
    // any #ifdef guards, so we treat them as if they were dependent.
    //
    // See the comment in FileGenerator::GenerateInlineFunctionDefinitions
    // for a more complete explanation.
    if (use_dependent_base_ && IsFieldDependent(field)) {
      map<string, string> vars;
      SetCommonFieldVariables(field, &vars, options_);
      vars["inline"] = "inline ";
      if (field->containing_oneof()) {
        vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
        vars["oneof_name"] = field->containing_oneof()->name();
        vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
        GenerateOneofMemberHasBits(field, vars, printer);
      } else if (!field->is_repeated()) {
        // There will be no header guard, so this always has to be inline.
        GenerateSingularFieldHasBits(field, vars, printer);
      }
      // vars needed for clear_(), which is in the dependent base:
      // (See also GenerateDependentFieldAccessorDeclarations.)
      vars["tmpl"] = "template<class T>\n";
      vars["dependent_classname"] =
          DependentBaseClassTemplateName(descriptor_) + "<T>";
      vars["this_message"] = DependentBaseDownCast();
      vars["this_const_message"] = DependentBaseConstDownCast();
      GenerateFieldClear(field, vars, printer);
    }

    // Generate type-specific accessors.
    field_generators_.get(field)
        .GenerateDependentInlineAccessorDefinitions(printer);

    printer->Print("\n");
  }

  // Generate has_$name$() and clear_has_$name$() functions for oneofs
  // Similar to other has-bits, these must always be in the header if we
  // are using a dependent base class.
  GenerateOneofHasBits(printer, true /* is_inline */);
}

void MessageGenerator::
GenerateSingularFieldHasBits(const FieldDescriptor* field,
                             map<string, string> vars,
                             io::Printer* printer) {
  if (HasFieldPresence(descriptor_->file())) {
    // N.B.: without field presence, we do not use has-bits or generate
    // has_$name$() methods.
    vars["has_array_index"] = SimpleItoa(field->index() / 32);
    vars["has_mask"] = StrCat(strings::Hex(1u << (field->index() % 32),
                                           strings::ZERO_PAD_8));
    printer->Print(vars,
      "$inline$"
      "bool $classname$::has_$name$() const {\n"
      "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
      "}\n"
      "$inline$"
      "void $classname$::set_has_$name$() {\n"
      "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
      "}\n"
      "$inline$"
      "void $classname$::clear_has_$name$() {\n"
      "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
      "}\n");
  } else {
    // Message fields have a has_$name$() method.
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      bool is_lazy = false;
      if (is_lazy) {
        printer->Print(vars,
          "$inline$"
          "bool $classname$::has_$name$() const {\n"
          "  return !$name$_.IsCleared();\n"
          "}\n");
      } else {
        printer->Print(vars,
          "$inline$"
          "bool $classname$::has_$name$() const {\n"
          "  return !_is_default_instance_ && $name$_ != NULL;\n"
          "}\n");
      }
    }
  }
}

void MessageGenerator::
GenerateOneofHasBits(io::Printer* printer, bool is_inline) {
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    map<string, string> vars;
    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
    vars["cap_oneof_name"] =
        ToUpper(descriptor_->oneof_decl(i)->name());
    vars["classname"] = classname_;
    vars["inline"] = (is_inline ? "inline " : "");
    printer->Print(
        vars,
        "$inline$"
        "bool $classname$::has_$oneof_name$() const {\n"
        "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
        "}\n"
        "$inline$"
        "void $classname$::clear_has_$oneof_name$() {\n"
        "  _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
        "}\n");
  }
}

void MessageGenerator::
GenerateOneofMemberHasBits(const FieldDescriptor* field,
                           const map<string, string>& vars,
                           io::Printer* printer) {
  // Singular field in a oneof
  // N.B.: Without field presence, we do not use has-bits or generate
  // has_$name$() methods, but oneofs still have set_has_$name$().
  // Oneofs also have has_$name$() but only as a private helper
  // method, so that generated code is slightly cleaner (vs.  comparing
  // _oneof_case_[index] against a constant everywhere).
  printer->Print(vars,
    "$inline$"
    "bool $classname$::has_$name$() const {\n"
    "  return $oneof_name$_case() == k$field_name$;\n"
    "}\n");
  printer->Print(vars,
    "$inline$"
    "void $classname$::set_has_$name$() {\n"
    "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
    "}\n");
}

void MessageGenerator::
GenerateFieldClear(const FieldDescriptor* field,
                   const map<string, string>& vars,
                   io::Printer* printer) {
  // Generate clear_$name$() (See GenerateFieldAccessorDeclarations and
  // GenerateDependentFieldAccessorDeclarations, $dependent_classname$ is
  // set by the Generate*Definitions functions.)
  printer->Print(vars,
    "$tmpl$"
    "$inline$"
    "void $dependent_classname$::clear_$name$() {\n");

  printer->Indent();

  if (field->containing_oneof()) {
    // Clear this field only if it is the active field in this oneof,
    // otherwise ignore
    printer->Print(vars,
      "if ($this_message$has_$name$()) {\n");
    printer->Indent();
    field_generators_.get(field)
        .GenerateClearingCode(printer);
    printer->Print(vars,
      "$this_message$clear_has_$oneof_name$();\n");
    printer->Outdent();
    printer->Print("}\n");
  } else {
    field_generators_.get(field)
        .GenerateClearingCode(printer);
    if (HasFieldPresence(descriptor_->file())) {
      if (!field->is_repeated()) {
        printer->Print(vars,
                       "$this_message$clear_has_$name$();\n");
      }
    }
  }

  printer->Outdent();
  printer->Print("}\n");
}

void MessageGenerator::
GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
  printer->Print("// $classname$\n\n", "classname", classname_);

  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    PrintFieldComment(printer, field);

    map<string, string> vars;
    SetCommonFieldVariables(field, &vars, options_);
    vars["inline"] = is_inline ? "inline " : "";
    if (use_dependent_base_ && IsFieldDependent(field)) {
      vars["tmpl"] = "template<class T>\n";
      vars["dependent_classname"] =
          DependentBaseClassTemplateName(descriptor_) + "<T>";
      vars["this_message"] = "reinterpret_cast<T*>(this)->";
      vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
    } else {
      vars["tmpl"] = "";
      vars["dependent_classname"] = vars["classname"];
      vars["this_message"] = "";
      vars["this_const_message"] = "";
    }

    // Generate has_$name$() or $name$_size().
    if (field->is_repeated()) {
      printer->Print(vars,
        "$inline$"
        "int $classname$::$name$_size() const {\n"
        "  return $name$_.size();\n"
        "}\n");
    } else if (field->containing_oneof()) {
      vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
      vars["oneof_name"] = field->containing_oneof()->name();
      vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
      if (!use_dependent_base_ || !IsFieldDependent(field)) {
        GenerateOneofMemberHasBits(field, vars, printer);
      }
    } else {
      // Singular field.
      if (!use_dependent_base_ || !IsFieldDependent(field)) {
        GenerateSingularFieldHasBits(field, vars, printer);
      }
    }

    if (!use_dependent_base_ || !IsFieldDependent(field)) {
      GenerateFieldClear(field, vars, printer);
    }

    // Generate type-specific accessors.
    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer,
                                                                   is_inline);

    printer->Print("\n");
  }

  if (!use_dependent_base_) {
    // Generate has_$name$() and clear_has_$name$() functions for oneofs
    // If we aren't using a dependent base, they can be with the other functions
    // that are #ifdef-guarded.
    GenerateOneofHasBits(printer, is_inline);
  }
}

// Helper for the code that emits the Clear() method.
static bool CanClearByZeroing(const FieldDescriptor* field) {
  if (field->is_repeated() || field->is_extension()) return false;
  switch (field->cpp_type()) {
    case internal::WireFormatLite::CPPTYPE_ENUM:
      return field->default_value_enum()->number() == 0;
    case internal::WireFormatLite::CPPTYPE_INT32:
      return field->default_value_int32() == 0;
    case internal::WireFormatLite::CPPTYPE_INT64:
      return field->default_value_int64() == 0;
    case internal::WireFormatLite::CPPTYPE_UINT32:
      return field->default_value_uint32() == 0;
    case internal::WireFormatLite::CPPTYPE_UINT64:
      return field->default_value_uint64() == 0;
    case internal::WireFormatLite::CPPTYPE_FLOAT:
      return field->default_value_float() == 0;
    case internal::WireFormatLite::CPPTYPE_DOUBLE:
      return field->default_value_double() == 0;
    case internal::WireFormatLite::CPPTYPE_BOOL:
      return field->default_value_bool() == false;
    default:
      return false;
  }
}

void MessageGenerator::
GenerateDependentBaseClassDefinition(io::Printer* printer) {
  if (!use_dependent_base_) {
    return;
  }

  map<string, string> vars;
  vars["classname"] = DependentBaseClassTemplateName(descriptor_);
  vars["superclass"] = SuperClassName(descriptor_, options_);

  printer->Print(vars,
    "template <class T>\n"
    "class $classname$ : public $superclass$ {\n"
    " public:\n");
  printer->Indent();

  printer->Print(vars,
    "$classname$() {}\n"
    "virtual ~$classname$() {}\n"
    "\n");

  // Generate dependent accessor methods for all fields.
  GenerateDependentFieldAccessorDeclarations(printer);

  printer->Outdent();
  printer->Print("};\n");
}

void MessageGenerator::
GenerateClassDefinition(io::Printer* printer) {
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // map entry message doesn't need class definition. Since map entry message
    // cannot be a top level class, we just need to avoid calling
    // GenerateClassDefinition here.
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->GenerateClassDefinition(printer);
    printer->Print("\n");
    printer->Print(kThinSeparator);
    printer->Print("\n");
  }

  if (use_dependent_base_) {
    GenerateDependentBaseClassDefinition(printer);
      printer->Print("\n");
  }

  map<string, string> vars;
  vars["classname"] = classname_;
  vars["field_count"] = SimpleItoa(descriptor_->field_count());
  vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
  if (options_.dllexport_decl.empty()) {
    vars["dllexport"] = "";
  } else {
    vars["dllexport"] = options_.dllexport_decl + " ";
  }
  if (use_dependent_base_) {
    vars["superclass"] =
        DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
  } else {
    vars["superclass"] = SuperClassName(descriptor_, options_);
  }
  printer->Print(vars,
    "class $dllexport$$classname$ : public $superclass$ {\n");
  printer->Annotate("classname", descriptor_);
  if (use_dependent_base_) {
    printer->Print(vars, "  friend class $superclass$;\n");
  }
  printer->Print(" public:\n");
  printer->Indent();

  printer->Print(vars,
    "$classname$();\n"
    "virtual ~$classname$();\n"
    "\n"
    "$classname$(const $classname$& from);\n"
    "\n"
    "inline $classname$& operator=(const $classname$& from) {\n"
    "  CopyFrom(from);\n"
    "  return *this;\n"
    "}\n"
    "\n");

  if (PreserveUnknownFields(descriptor_)) {
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
        "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
        "  return _internal_metadata_.unknown_fields();\n"
        "}\n"
        "\n"
        "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
        "  return _internal_metadata_.mutable_unknown_fields();\n"
        "}\n"
        "\n");
    } else {
      if (SupportsArenas(descriptor_)) {
        printer->Print(
          "inline const ::std::string& unknown_fields() const {\n"
          "  return _unknown_fields_.Get(\n"
          "      &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
          "}\n"
          "\n"
          "inline ::std::string* mutable_unknown_fields() {\n"
          "  return _unknown_fields_.Mutable(\n"
          "      &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
          "      GetArenaNoVirtual());\n"
          "}\n"
          "\n");
      } else {
        printer->Print(
          "inline const ::std::string& unknown_fields() const {\n"
          "  return _unknown_fields_.GetNoArena(\n"
          "      &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
          "}\n"
          "\n"
          "inline ::std::string* mutable_unknown_fields() {\n"
          "  return _unknown_fields_.MutableNoArena(\n"
          "      &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
          "}\n"
          "\n");
      }
    }
  }

  // N.B.: We exclude GetArena() when arena support is disabled, falling back on
  // MessageLite's implementation which returns NULL rather than generating our
  // own method which returns NULL, in order to reduce code size.
  if (SupportsArenas(descriptor_)) {
    // virtual method version of GetArenaNoVirtual(), required for generic dispatch given a
    // MessageLite* (e.g., in RepeatedField::AddAllocated()).
    printer->Print(
        "inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }\n"
        "inline void* GetMaybeArenaPointer() const {\n"
        "  return MaybeArenaPtr();\n"
        "}\n");
  }

  // Only generate this member if it's not disabled.
  if (HasDescriptorMethods(descriptor_->file(), options_) &&
      !descriptor_->options().no_standard_descriptor_accessor()) {
    printer->Print(vars,
      "static const ::google::protobuf::Descriptor* descriptor();\n");
  }

  printer->Print(vars,
    "static const $classname$& default_instance();\n"
    "\n");

  // Generate enum values for every field in oneofs. One list is generated for
  // each oneof with an additional *_NOT_SET value.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "enum $camel_oneof_name$Case {\n",
        "camel_oneof_name",
        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
    printer->Indent();
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      printer->Print(
          "k$field_name$ = $field_number$,\n",
          "field_name",
          UnderscoresToCamelCase(
              descriptor_->oneof_decl(i)->field(j)->name(), true),
          "field_number",
          SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
    }
    printer->Print(
        "$cap_oneof_name$_NOT_SET = 0,\n",
        "cap_oneof_name",
        ToUpper(descriptor_->oneof_decl(i)->name()));
    printer->Outdent();
    printer->Print(
        "};\n"
        "\n");
  }

  if (!StaticInitializersForced(descriptor_->file(), options_)) {
    printer->Print(vars,
      "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
      "// Returns the internal default instance pointer. This function can\n"
      "// return NULL thus should not be used by the user. This is intended\n"
      "// for Protobuf internal code. Please use default_instance() declared\n"
      "// above instead.\n"
      "static inline const $classname$* internal_default_instance() {\n"
      "  return default_instance_;\n"
      "}\n"
      "#endif\n"
      "\n");
  }


  if (SupportsArenas(descriptor_)) {
    printer->Print(vars,
      "void UnsafeArenaSwap($classname$* other);\n");
  }

  if (IsAnyMessage(descriptor_)) {
    printer->Print(vars,
      "// implements Any -----------------------------------------------\n"
      "\n"
      "void PackFrom(const ::google::protobuf::Message& message);\n"
      "void PackFrom(const ::google::protobuf::Message& message,\n"
      "              const ::std::string& type_url_prefix);\n"
      "bool UnpackTo(::google::protobuf::Message* message) const;\n"
      "template<typename T> bool Is() const {\n"
      "  return _any_metadata_.Is<T>();\n"
      "}\n"
      "\n");
  }

  printer->Print(vars,
    "void Swap($classname$* other);\n"
    "\n"
    "// implements Message ----------------------------------------------\n"
    "\n"
    "inline $classname$* New() const { return New(NULL); }\n"
    "\n"
    "$classname$* New(::google::protobuf::Arena* arena) const;\n");

  if (HasGeneratedMethods(descriptor_->file(), options_)) {
    if (HasDescriptorMethods(descriptor_->file(), options_)) {
      printer->Print(vars,
        "void CopyFrom(const ::google::protobuf::Message& from);\n"
        "void MergeFrom(const ::google::protobuf::Message& from);\n");
    } else {
      printer->Print(vars,
        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
    }

    printer->Print(vars,
      "void CopyFrom(const $classname$& from);\n"
      "void MergeFrom(const $classname$& from);\n"
      "void Clear();\n"
      "bool IsInitialized() const;\n"
      "\n"
      "int ByteSize() const;\n"
      "bool MergePartialFromCodedStream(\n"
      "    ::google::protobuf::io::CodedInputStream* input);\n"
      "void SerializeWithCachedSizes(\n"
      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
    // DiscardUnknownFields() is implemented in message.cc using reflections. We
    // need to implement this function in generated code for messages.
    if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
        "void DiscardUnknownFields();\n");
    }
    if (HasFastArraySerialization(descriptor_->file(), options_)) {
      printer->Print(
        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
    }
  }

  // Check all FieldDescriptors including those in oneofs to estimate
  // whether ::std::string is likely to be used, and depending on that
  // estimate, set uses_string_ to true or false.  That contols
  // whether to force initialization of empty_string_ in SharedCtor().
  // It's often advantageous to do so to keep "is empty_string_
  // inited?" code from appearing all over the place.
  vector<const FieldDescriptor*> descriptors;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    descriptors.push_back(descriptor_->field(i));
  }
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
    }
  }
  uses_string_ = false;
  if (PreserveUnknownFields(descriptor_) &&
      !UseUnknownFieldSet(descriptor_->file(), options_)) {
    uses_string_ = true;
  }
  for (int i = 0; i < descriptors.size(); i++) {
    const FieldDescriptor* field = descriptors[i];
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
      switch (field->options().ctype()) {
        default: uses_string_ = true; break;
      }
    }
  }

  printer->Print(
    "int GetCachedSize() const { return _cached_size_; }\n"
    "private:\n"
    "void SharedCtor();\n"
    "void SharedDtor();\n"
    "void SetCachedSize(int size) const;\n"
    "void InternalSwap($classname$* other);\n",
    "classname", classname_);
  if (SupportsArenas(descriptor_)) {
    printer->Print(
      "protected:\n"
      "explicit $classname$(::google::protobuf::Arena* arena);\n"
      "private:\n"
      "static void ArenaDtor(void* object);\n"
      "inline void RegisterArenaDtor(::google::protobuf::Arena* arena);\n",
      "classname", classname_);
  }

  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(
      "private:\n"
      "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
      "  return _internal_metadata_.arena();\n"
      "}\n"
      "inline void* MaybeArenaPtr() const {\n"
      "  return _internal_metadata_.raw_arena_ptr();\n"
      "}\n"
      "public:\n"
      "\n");
  } else {
    printer->Print(
      "private:\n"
      "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
      "  return _arena_ptr_;\n"
      "}\n"
      "inline ::google::protobuf::Arena* MaybeArenaPtr() const {\n"
      "  return _arena_ptr_;\n"
      "}\n"
      "public:\n"
      "\n");
  }

  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(
      "::google::protobuf::Metadata GetMetadata() const;\n"
      "\n");
  } else {
    printer->Print(
      "::std::string GetTypeName() const;\n"
      "\n");
  }

  printer->Print(
    "// nested types ----------------------------------------------------\n"
    "\n");

  // Import all nested message classes into this class's scope with typedefs.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    const Descriptor* nested_type = descriptor_->nested_type(i);
    if (!IsMapEntryMessage(nested_type)) {
      printer->Print("typedef $nested_full_name$ $nested_name$;\n",
                     "nested_name", nested_type->name(),
                     "nested_full_name", ClassName(nested_type, false));
    }
  }

  if (descriptor_->nested_type_count() > 0) {
    printer->Print("\n");
  }

  // Import all nested enums and their values into this class's scope with
  // typedefs and constants.
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    enum_generators_[i]->GenerateSymbolImports(printer);
    printer->Print("\n");
  }

  printer->Print(
    "// accessors -------------------------------------------------------\n"
    "\n");

  // Generate accessor methods for all fields.
  GenerateFieldAccessorDeclarations(printer);

  // Declare extension identifiers.
  for (int i = 0; i < descriptor_->extension_count(); i++) {
    extension_generators_[i]->GenerateDeclaration(printer);
  }


  printer->Print(
    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
    "full_name", descriptor_->full_name());

  // Generate private members.
  printer->Outdent();
  printer->Print(" private:\n");
  printer->Indent();


  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (!descriptor_->field(i)->is_repeated()) {
      // set_has_***() generated in all proto1/2 code and in oneofs (only) for
      // messages without true field presence.
      if (HasFieldPresence(descriptor_->file()) ||
          descriptor_->field(i)->containing_oneof()) {
        printer->Print(
          "inline void set_has_$name$();\n",
          "name", FieldName(descriptor_->field(i)));
      }
      // clear_has_***() generated only for non-oneof fields
      // in proto1/2.
      if (!descriptor_->field(i)->containing_oneof() &&
          HasFieldPresence(descriptor_->file())) {
        printer->Print(
          "inline void clear_has_$name$();\n",
          "name", FieldName(descriptor_->field(i)));
      }
    }
  }
  printer->Print("\n");

  // Generate oneof function declarations
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "inline bool has_$oneof_name$() const;\n"
        "void clear_$oneof_name$();\n"
        "inline void clear_has_$oneof_name$();\n\n",
        "oneof_name", descriptor_->oneof_decl(i)->name());
  }

  if (HasGeneratedMethods(descriptor_->file(), options_) &&
      !descriptor_->options().message_set_wire_format() &&
      num_required_fields_ > 1) {
    printer->Print(
        "// helper for ByteSize()\n"
        "int RequiredFieldsByteSizeFallback() const;\n\n");
  }

  // Prepare decls for _cached_size_ and _has_bits_.  Their position in the
  // output will be determined later.

  bool need_to_emit_cached_size = true;
  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
  const string cached_size_decl = "mutable int _cached_size_;\n";

  // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
  size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
  if (descriptor_->field_count() == 0) {
    // Zero-size arrays aren't technically allowed, and MSVC in particular
    // doesn't like them.  We still need to declare these arrays to make
    // other code compile.  Since this is an uncommon case, we'll just declare
    // them with size 1 and waste some space.  Oh well.
    sizeof_has_bits = 4;
  }
  const string has_bits_decl = sizeof_has_bits == 0 ? "" :
      "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";


  // To minimize padding, data members are divided into three sections:
  // (1) members assumed to align to 8 bytes
  // (2) members corresponding to message fields, re-ordered to optimize
  //     alignment.
  // (3) members assumed to align to 4 bytes.

  // Members assumed to align to 8 bytes:

  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
      "::google::protobuf::internal::ExtensionSet _extensions_;\n"
      "\n");
  }

  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(
      "::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
  } else {
    printer->Print(
      "::google::protobuf::internal::ArenaStringPtr _unknown_fields_;\n"
      "::google::protobuf::Arena* _arena_ptr_;\n"
      "\n");
  }

  if (SupportsArenas(descriptor_)) {
    printer->Print(
      "friend class ::google::protobuf::Arena;\n"
      "typedef void InternalArenaConstructable_;\n"
      "typedef void DestructorSkippable_;\n");
  }

  if (HasFieldPresence(descriptor_->file())) {
    // _has_bits_ is frequently accessed, so to reduce code size and improve
    // speed, it should be close to the start of the object.  But, try not to
    // waste space:_has_bits_ by itself always makes sense if its size is a
    // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
    // will work well.
    printer->Print(has_bits_decl.c_str());
    if ((sizeof_has_bits % 8) != 0) {
      printer->Print(cached_size_decl.c_str());
      need_to_emit_cached_size = false;
    }
  } else {
    // Without field presence, we need another way to disambiguate the default
    // instance, because the default instance's submessage fields (if any) store
    // pointers to the default instances of the submessages even when they
    // aren't present. Alternatives to this approach might be to (i) use a
    // tagged pointer on all message fields, setting a tag bit for "not really
    // present, just default instance"; or (ii) comparing |this| against the
    // return value from GeneratedMessageFactory::GetPrototype() in all
    // has_$field$() calls. However, both of these options are much more
    // expensive (in code size and CPU overhead) than just checking a field in
    // the message. Long-term, the best solution would be to rearchitect the
    // default instance design not to store pointers to submessage default
    // instances, and have reflection get those some other way; but that change
    // would have too much impact on proto2.
    printer->Print(
      "bool _is_default_instance_;\n");
  }

  // Field members:

  // List fields which doesn't belong to any oneof
  vector<const FieldDescriptor*> fields;
  hash_map<string, int> fieldname_to_chunk;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (!descriptor_->field(i)->containing_oneof()) {
      const FieldDescriptor* field = descriptor_->field(i);
      fields.push_back(field);
      fieldname_to_chunk[FieldName(field)] = i / 8;
    }
  }
  OptimizePadding(&fields);
  // Emit some private and static members
  runs_of_fields_ = vector< vector<string> >(1);
  for (int i = 0; i < fields.size(); ++i) {
    const FieldDescriptor* field = fields[i];
    const FieldGenerator& generator = field_generators_.get(field);
    generator.GenerateStaticMembers(printer);
    generator.GeneratePrivateMembers(printer);
    if (CanClearByZeroing(field)) {
      const string& fieldname = FieldName(field);
      if (!runs_of_fields_.back().empty() &&
          (fieldname_to_chunk[runs_of_fields_.back().back()] !=
           fieldname_to_chunk[fieldname])) {
        runs_of_fields_.push_back(vector<string>());
      }
      runs_of_fields_.back().push_back(fieldname);
    } else if (!runs_of_fields_.back().empty()) {
      runs_of_fields_.push_back(vector<string>());
    }
  }

  // For each oneof generate a union
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "union $camel_oneof_name$Union {\n"
        // explicit empty constructor is needed when union contains
        // ArenaStringPtr members for string fields.
        "  $camel_oneof_name$Union() {}\n",
        "camel_oneof_name",
        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
    printer->Indent();
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      field_generators_.get(descriptor_->oneof_decl(i)->
                            field(j)).GeneratePrivateMembers(printer);
    }
    printer->Outdent();
    printer->Print(
        "} $oneof_name$_;\n",
        "oneof_name", descriptor_->oneof_decl(i)->name());
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      field_generators_.get(descriptor_->oneof_decl(i)->
                            field(j)).GenerateStaticMembers(printer);
    }
  }

  // Members assumed to align to 4 bytes:

  if (need_to_emit_cached_size) {
    printer->Print(cached_size_decl.c_str());
    need_to_emit_cached_size = false;
  }

  // Generate _oneof_case_.
  if (descriptor_->oneof_decl_count() > 0) {
    printer->Print(vars,
      "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
      "\n");
  }

  // Generate _any_metadata_ for the Any type.
  if (IsAnyMessage(descriptor_)) {
    printer->Print(vars,
      "::google::protobuf::internal::AnyMetadata _any_metadata_;\n");
  }

  // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
  // friends so that they can access private static variables like
  // default_instance_ and reflection_.
  PrintHandlingOptionalStaticInitializers(
      descriptor_->file(), options_, printer,
      // With static initializers.
      "friend void $dllexport_decl$ $adddescriptorsname$();\n",
      // Without.
      "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
      // Vars.
      "dllexport_decl", options_.dllexport_decl, "adddescriptorsname",
      GlobalAddDescriptorsName(descriptor_->file()->name()));

  printer->Print(
    "friend void $assigndescriptorsname$();\n"
    "friend void $shutdownfilename$();\n"
    "\n",
    "assigndescriptorsname",
      GlobalAssignDescriptorsName(descriptor_->file()->name()),
    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));

  printer->Print(
    "void InitAsDefaultInstance();\n"
    "static $classname$* default_instance_;\n",
    "classname", classname_);

  printer->Outdent();
  printer->Print(vars, "};");
  GOOGLE_DCHECK(!need_to_emit_cached_size);
}

void MessageGenerator::
GenerateDependentInlineMethods(io::Printer* printer) {
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // map entry message doesn't need inline methods. Since map entry message
    // cannot be a top level class, we just need to avoid calling
    // GenerateInlineMethods here.
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->GenerateDependentInlineMethods(printer);
    printer->Print(kThinSeparator);
    printer->Print("\n");
  }

  GenerateDependentFieldAccessorDefinitions(printer);
}

void MessageGenerator::
GenerateInlineMethods(io::Printer* printer, bool is_inline) {
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // map entry message doesn't need inline methods. Since map entry message
    // cannot be a top level class, we just need to avoid calling
    // GenerateInlineMethods here.
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->GenerateInlineMethods(printer, is_inline);
    printer->Print(kThinSeparator);
    printer->Print("\n");
  }

  GenerateFieldAccessorDefinitions(printer, is_inline);

  // Generate oneof_case() functions.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    map<string, string> vars;
    vars["class_name"] = classname_;
    vars["camel_oneof_name"] = UnderscoresToCamelCase(
        descriptor_->oneof_decl(i)->name(), true);
    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
    vars["inline"] = is_inline ? "inline " : "";
    printer->Print(
        vars,
        "$inline$"
        "$class_name$::$camel_oneof_name$Case $class_name$::"
        "$oneof_name$_case() const {\n"
        "  return $class_name$::$camel_oneof_name$Case("
        "_oneof_case_[$oneof_index$]);\n"
        "}\n");
  }
}

void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer* printer) {
  if (!IsMapEntryMessage(descriptor_)) {
    printer->Print(
      "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
      "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
      "  $name$_reflection_ = NULL;\n",
      "name", classname_);
  } else {
    printer->Print(
      "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
      "name", classname_);
  }

  // Generate oneof default instance for reflection usage.
  if (descriptor_->oneof_decl_count() > 0) {
    printer->Print("struct $name$OneofInstance {\n",
                   "name", classname_);
    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
        printer->Print("  ");
        if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
            (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
             EffectiveStringCType(field) != FieldOptions::STRING)) {
          printer->Print("const ");
        }
        field_generators_.get(field).GeneratePrivateMembers(printer);
      }
    }

    printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
                   "name", classname_);
  }

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
  }

  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    printer->Print(
      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
      "name", ClassName(descriptor_->enum_type(i), false));
  }
}

void MessageGenerator::
GenerateDescriptorInitializer(io::Printer* printer, int index) {
  // TODO(kenton):  Passing the index to this method is redundant; just use
  //   descriptor_->index() instead.
  map<string, string> vars;
  vars["classname"] = classname_;
  vars["index"] = SimpleItoa(index);

  // Obtain the descriptor from the parent's descriptor.
  if (descriptor_->containing_type() == NULL) {
    printer->Print(vars,
      "$classname$_descriptor_ = file->message_type($index$);\n");
  } else {
    vars["parent"] = ClassName(descriptor_->containing_type(), false);
    printer->Print(vars,
      "$classname$_descriptor_ = "
        "$parent$_descriptor_->nested_type($index$);\n");
  }

  if (IsMapEntryMessage(descriptor_)) return;

  // Generate the offsets.
  GenerateOffsets(printer);

  const bool pass_pool_and_factory = false;
  vars["fn"] = pass_pool_and_factory ?
      "new ::google::protobuf::internal::GeneratedMessageReflection" :
      "::google::protobuf::internal::GeneratedMessageReflection"
      "::NewGeneratedMessageReflection";
  // Construct the reflection object.
  printer->Print(vars,
    "$classname$_reflection_ =\n"
    "  $fn$(\n"
    "    $classname$_descriptor_,\n"
    "    $classname$::default_instance_,\n"
    "    $classname$_offsets_,\n");
  if (!HasFieldPresence(descriptor_->file())) {
    // If we don't have field presence, then _has_bits_ does not exist.
    printer->Print(vars,
    "    -1,\n");
  } else {
    printer->Print(vars,
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n");
  }

  // Unknown field offset: either points to the unknown field set if embedded
  // directly, or indicates that the unknown field set is stored as part of the
  // internal metadata if not.
  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(vars,
    "    -1,\n");
  } else {
    printer->Print(vars,
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
      "$classname$, _unknown_fields_),\n");
  }

  if (descriptor_->extension_range_count() > 0) {
    printer->Print(vars,
      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
        "$classname$, _extensions_),\n");
  } else {
    // No extensions.
    printer->Print(vars,
      "    -1,\n");
  }

  if (descriptor_->oneof_decl_count() > 0) {
    printer->Print(vars,
    "    $classname$_default_oneof_instance_,\n"
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
      "$classname$, _oneof_case_[0]),\n");
  }

  if (pass_pool_and_factory) {
    printer->Print(
        "    ::google::protobuf::DescriptorPool::generated_pool(),\n");
      printer->Print(vars,
                     "    ::google::protobuf::MessageFactory::generated_factory(),\n");
  }

  printer->Print(vars,
    "    sizeof($classname$),\n");

  // Arena offset: either an offset to the metadata struct that contains the
  // arena pointer and unknown field set (in a space-efficient way) if we use
  // that implementation strategy, or an offset directly to the arena pointer if
  // not (because e.g. we don't have an unknown field set).
  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(vars,
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
    "$classname$, _internal_metadata_),\n");
  } else {
    printer->Print(vars,
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
    "$classname$, _arena_),\n");
  }

  // is_default_instance_ offset.
  if (HasFieldPresence(descriptor_->file())) {
    printer->Print(vars,
    "    -1);\n");
  } else {
    printer->Print(vars,
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
    "$classname$, _is_default_instance_));\n");
  }

  // Handle nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
  }

  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
  }
}

void MessageGenerator::
GenerateTypeRegistrations(io::Printer* printer) {
  // Register this message type with the message factory.
  if (!IsMapEntryMessage(descriptor_)) {
    printer->Print(
      "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
      "    $classname$_descriptor_, &$classname$::default_instance());\n",
      "classname", classname_);
  }
  else {
    map<string, string> vars;
    CollectMapInfo(descriptor_, &vars);
    vars["classname"] = classname_;

    const FieldDescriptor* val = descriptor_->FindFieldByName("value");
    if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
        val->type() == FieldDescriptor::TYPE_ENUM) {
      const EnumValueDescriptor* default_value = val->default_value_enum();
      vars["default_enum_value"] = Int32ToString(default_value->number());
    } else {
      vars["default_enum_value"] = "0";
    }

    printer->Print(vars,
      "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
      "      $classname$_descriptor_,\n"
      "      ::google::protobuf::internal::MapEntry<\n"
      "          $key$,\n"
      "          $val$,\n"
      "          $key_wire_type$,\n"
      "          $val_wire_type$,\n"
      "          $default_enum_value$>::CreateDefaultInstance(\n"
      "              $classname$_descriptor_));\n");
  }

  // Handle nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->GenerateTypeRegistrations(printer);
  }
}

void MessageGenerator::
GenerateDefaultInstanceAllocator(io::Printer* printer) {
  // Construct the default instances of all fields, as they will be used
  // when creating the default instance of the entire message.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    field_generators_.get(descriptor_->field(i))
                     .GenerateDefaultInstanceAllocator(printer);
  }

  if (IsMapEntryMessage(descriptor_)) return;

  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
  // because we need to make sure all default instances that this one might
  // depend on are constructed first.
  printer->Print(
    "$classname$::default_instance_ = new $classname$();\n",
    "classname", classname_);

  if ((descriptor_->oneof_decl_count() > 0) &&
      HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(
    "$classname$_default_oneof_instance_ = new $classname$OneofInstance();\n",
    "classname", classname_);
  }

  // Handle nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
  }

}

void MessageGenerator::
GenerateDefaultInstanceInitializer(io::Printer* printer) {
  printer->Print(
    "$classname$::default_instance_->InitAsDefaultInstance();\n",
    "classname", classname_);

  // Register extensions.
  for (int i = 0; i < descriptor_->extension_count(); i++) {
    extension_generators_[i]->GenerateRegistration(printer);
  }

  // Handle nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // map entry message doesn't need to initialize default instance manually.
    // Since map entry message cannot be a top level class, we just need to
    // avoid calling DefaultInstanceInitializer here.
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
  }
}

void MessageGenerator::
GenerateShutdownCode(io::Printer* printer) {
  printer->Print(
    "delete $classname$::default_instance_;\n",
    "classname", classname_);

  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    if (descriptor_->oneof_decl_count() > 0) {
      printer->Print(
        "delete $classname$_default_oneof_instance_;\n",
        "classname", classname_);
    }
    printer->Print(
      "delete $classname$_reflection_;\n",
      "classname", classname_);
  }

  // Handle default instances of fields.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    field_generators_.get(descriptor_->field(i))
                     .GenerateShutdownCode(printer);
  }

  // Handle nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->GenerateShutdownCode(printer);
  }
}

void MessageGenerator::
GenerateClassMethods(io::Printer* printer) {
  // mutable_unknown_fields wrapper function for LazyStringOutputStream
  // callback.
  if (PreserveUnknownFields(descriptor_) &&
      !UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(
        "static ::std::string* MutableUnknownFieldsFor$classname$(\n"
        "    $classname$* ptr) {\n"
        "  return ptr->mutable_unknown_fields();\n"
        "}\n"
        "\n",
        "classname", classname_);
  }
  if (IsAnyMessage(descriptor_)) {
    printer->Print(
      "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n"
      "  _any_metadata_.PackFrom(message);\n"
      "}\n"
      "\n"
      "void $classname$::PackFrom(const ::google::protobuf::Message& message,\n"
      "                           const ::std::string& type_url_prefix) {\n"
      "  _any_metadata_.PackFrom(message, type_url_prefix);\n"
      "}\n"
      "\n"
      "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n"
      "  return _any_metadata_.UnpackTo(message);\n"
      "}\n"
      "\n",
      "classname", classname_);
  }

  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    enum_generators_[i]->GenerateMethods(printer);
  }

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // map entry message doesn't need class methods. Since map entry message
    // cannot be a top level class, we just need to avoid calling
    // GenerateClassMethods here.
    if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
    nested_generators_[i]->GenerateClassMethods(printer);
    printer->Print("\n");
    printer->Print(kThinSeparator);
    printer->Print("\n");
  }

  // Generate non-inline field definitions.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    field_generators_.get(descriptor_->field(i))
                     .GenerateNonInlineAccessorDefinitions(printer);
  }

  // Generate field number constants.
  printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor *field = descriptor_->field(i);
    printer->Print(
      "const int $classname$::$constant_name$;\n",
      "classname", ClassName(FieldScope(field), false),
      "constant_name", FieldConstantName(field));
  }
  printer->Print(
    "#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
    "\n");

  // Define extension identifiers.
  for (int i = 0; i < descriptor_->extension_count(); i++) {
    extension_generators_[i]->GenerateDefinition(printer);
  }

  GenerateStructors(printer);
  printer->Print("\n");

  if (descriptor_->oneof_decl_count() > 0) {
    GenerateOneofClear(printer);
    printer->Print("\n");
  }

  if (HasGeneratedMethods(descriptor_->file(), options_)) {
    GenerateClear(printer);
    printer->Print("\n");

    GenerateMergeFromCodedStream(printer);
    printer->Print("\n");

    GenerateSerializeWithCachedSizes(printer);
    printer->Print("\n");

    if (HasFastArraySerialization(descriptor_->file(), options_)) {
      GenerateSerializeWithCachedSizesToArray(printer);
      printer->Print("\n");
    }

    GenerateByteSize(printer);
    printer->Print("\n");

    GenerateMergeFrom(printer);
    printer->Print("\n");

    GenerateCopyFrom(printer);
    printer->Print("\n");

    GenerateIsInitialized(printer);
    printer->Print("\n");
  }

  GenerateSwap(printer);
  printer->Print("\n");

  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(
      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
      "  protobuf_AssignDescriptorsOnce();\n"
      "  ::google::protobuf::Metadata metadata;\n"
      "  metadata.descriptor = $classname$_descriptor_;\n"
      "  metadata.reflection = $classname$_reflection_;\n"
      "  return metadata;\n"
      "}\n"
      "\n",
      "classname", classname_);
  } else {
    printer->Print(
      "::std::string $classname$::GetTypeName() const {\n"
      "  return \"$type_name$\";\n"
      "}\n"
      "\n",
      "classname", classname_,
      "type_name", descriptor_->full_name());
  }

}

void MessageGenerator::
GenerateOffsets(io::Printer* printer) {
  printer->Print("static const int $classname$_offsets_[$field_count$] = {\n",
                 "classname", classname_, "field_count",
                 SimpleItoa(std::max(1, descriptor_->field_count() +
                                            descriptor_->oneof_decl_count())));
  printer->Indent();

  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (field->containing_oneof()) {
      printer->Print(
          "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
          "$classname$_default_oneof_instance_, $name$_),\n",
          "classname", classname_,
          "name", FieldName(field));
    } else {
      printer->Print(
          "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
                                                 "$name$_),\n",
          "classname", classname_,
          "name", FieldName(field));
    }
  }

  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
    printer->Print(
      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
      "classname", classname_,
      "name", oneof->name());
  }

  printer->Outdent();
  printer->Print("};\n");
}

void MessageGenerator::
GenerateSharedConstructorCode(io::Printer* printer) {
  printer->Print(
    "void $classname$::SharedCtor() {\n",
    "classname", classname_);
  printer->Indent();

  if (!HasFieldPresence(descriptor_->file())) {
    printer->Print(
      "  _is_default_instance_ = false;\n");
  }

  printer->Print(StrCat(
      uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
      "_cached_size_ = 0;\n").c_str());

  if (PreserveUnknownFields(descriptor_) &&
      !UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(
        "_unknown_fields_.UnsafeSetDefault(\n"
        "    &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
  }

  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (!descriptor_->field(i)->containing_oneof()) {
      field_generators_.get(descriptor_->field(i))
          .GenerateConstructorCode(printer);
    }
  }

  if (HasFieldPresence(descriptor_->file())) {
    printer->Print(
      "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
  }

  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "clear_has_$oneof_name$();\n",
        "oneof_name", descriptor_->oneof_decl(i)->name());
  }

  printer->Outdent();
  printer->Print("}\n\n");
}

void MessageGenerator::
GenerateSharedDestructorCode(io::Printer* printer) {
  printer->Print(
    "void $classname$::SharedDtor() {\n",
    "classname", classname_);
  printer->Indent();
  if (SupportsArenas(descriptor_)) {
    // Do nothing when the message is allocated in an arena.
    printer->Print(
      "if (GetArenaNoVirtual() != NULL) {\n"
      "  return;\n"
      "}\n"
      "\n");
  }

  // Write the desctructor for _unknown_fields_ in lite runtime.
  if (PreserveUnknownFields(descriptor_) &&
      !UseUnknownFieldSet(descriptor_->file(), options_)) {
    if (SupportsArenas(descriptor_)) {
      printer->Print(
          "_unknown_fields_.Destroy(\n"
          "    &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
          "    GetArenaNoVirtual());\n");
    } else {
      printer->Print(
          "_unknown_fields_.DestroyNoArena(\n"
          "    &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
    }
  }

  // Write the destructors for each field except oneof members.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (!descriptor_->field(i)->containing_oneof()) {
      field_generators_.get(descriptor_->field(i))
                       .GenerateDestructorCode(printer);
    }
  }

  // Generate code to destruct oneofs. Clearing should do the work.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "if (has_$oneof_name$()) {\n"
        "  clear_$oneof_name$();\n"
        "}\n",
        "oneof_name", descriptor_->oneof_decl(i)->name());
  }

  PrintHandlingOptionalStaticInitializers(
      descriptor_->file(), options_, printer,
      // With static initializers.
      "if (this != default_instance_) {\n",
      // Without.
      "if (this != &default_instance()) {\n");

  // We need to delete all embedded messages.
  // TODO(kenton):  If we make unset messages point at default instances
  //   instead of NULL, then it would make sense to move this code into
  //   MessageFieldGenerator::GenerateDestructorCode().
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    if (!field->is_repeated() &&
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      // Skip oneof members
      if (!field->containing_oneof()) {
        printer->Print(
            "  delete $name$_;\n",
            "name", FieldName(field));
      }
    }
  }

  printer->Outdent();
  printer->Print(
    "  }\n"
    "}\n"
    "\n");
}

void MessageGenerator::
GenerateArenaDestructorCode(io::Printer* printer) {
  // Generate the ArenaDtor() method. Track whether any fields actually produced
  // code that needs to be called.
  printer->Print(
      "void $classname$::ArenaDtor(void* object) {\n",
      "classname", classname_);
  printer->Indent();

  // This code is placed inside a static method, rather than an ordinary one,
  // since that simplifies Arena's destructor list (ordinary function pointers
  // rather than member function pointers). _this is the object being
  // destructed.
  printer->Print(
      "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
      // avoid an "unused variable" warning in case no fields have dtor code.
      "(void)_this;\n",
      "classname", classname_);

  bool need_registration = false;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (field_generators_.get(descriptor_->field(i))
                         .GenerateArenaDestructorCode(printer)) {
      need_registration = true;
    }
  }
  printer->Outdent();
  printer->Print(
      "}\n");

  if (need_registration) {
    printer->Print(
        "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
        "  if (arena != NULL) {\n"
        "    arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
        "  }\n"
        "}\n",
        "classname", classname_);
  } else {
    printer->Print(
        "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
        "}\n",
        "classname", classname_);
  }
}

void MessageGenerator::
GenerateStructors(io::Printer* printer) {
  string superclass;
  if (use_dependent_base_) {
    superclass =
        DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
  } else {
    superclass = SuperClassName(descriptor_, options_);
  }
  string initializer_with_arena = superclass + "()";

  if (descriptor_->extension_range_count() > 0) {
    initializer_with_arena += ",\n  _extensions_(arena)";
  }

  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
    initializer_with_arena += ",\n  _internal_metadata_(arena)";
  } else {
    initializer_with_arena += ",\n  _arena_ptr_(arena)";
  }

  // Initialize member variables with arena constructor.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    bool has_arena_constructor = descriptor_->field(i)->is_repeated();
    if (has_arena_constructor) {
      initializer_with_arena += string(",\n  ") +
          FieldName(descriptor_->field(i)) + string("_(arena)");
    }
  }

  if (IsAnyMessage(descriptor_)) {
    initializer_with_arena += ",\n  _any_metadata_(&type_url, &value_)";
  }

  string initializer_null;
  initializer_null = (UseUnknownFieldSet(descriptor_->file(), options_) ?
    ", _internal_metadata_(NULL)" : ", _arena_ptr_(NULL)");
  if (IsAnyMessage(descriptor_)) {
    initializer_null += ", _any_metadata_(&type_url_, &value_)";
  }

  printer->Print(
      "$classname$::$classname$()\n"
      "  : $superclass$()$initializer$ {\n"
      "  SharedCtor();\n"
      "  // @@protoc_insertion_point(constructor:$full_name$)\n"
      "}\n",
      "classname", classname_,
      "superclass", superclass,
      "full_name", descriptor_->full_name(),
      "initializer", initializer_null);

  if (SupportsArenas(descriptor_)) {
    printer->Print(
        "\n"
        "$classname$::$classname$(::google::protobuf::Arena* arena)\n"
        "  : $initializer$ {\n"
        "  SharedCtor();\n"
        "  RegisterArenaDtor(arena);\n"
        "  // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
        "}\n",
        "initializer", initializer_with_arena,
        "classname", classname_,
        "superclass", superclass,
        "full_name", descriptor_->full_name());
  }

  printer->Print(
    "\n"
    "void $classname$::InitAsDefaultInstance() {\n",
    "classname", classname_);

  if (!HasFieldPresence(descriptor_->file())) {
    printer->Print(
      "  _is_default_instance_ = true;\n");
  }

  // The default instance needs all of its embedded message pointers
  // cross-linked to other default instances.  We can't do this initialization
  // in the constructor because some other default instances may not have been
  // constructed yet at that time.
  // TODO(kenton):  Maybe all message fields (even for non-default messages)
  //   should be initialized to point at default instances rather than NULL?
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    if (!field->is_repeated() &&
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
        (field->containing_oneof() == NULL ||
         HasDescriptorMethods(descriptor_->file(), options_))) {
      string name;
      if (field->containing_oneof()) {
        name = classname_ + "_default_oneof_instance_->";
      }
      name += FieldName(field);
      PrintHandlingOptionalStaticInitializers(
          descriptor_->file(), options_, printer,
          // With static initializers.
          "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
          // Without.
          "  $name$_ = const_cast< $type$*>(\n"
          "      $type$::internal_default_instance());\n",
          // Vars.
          "name", name, "type", FieldMessageTypeName(field));
    } else if (field->containing_oneof() &&
               HasDescriptorMethods(descriptor_->file(), options_)) {
      field_generators_.get(descriptor_->field(i))
          .GenerateConstructorCode(printer);
    }
  }
  printer->Print(
    "}\n"
    "\n");

  // Generate the copy constructor.
  printer->Print(
    "$classname$::$classname$(const $classname$& from)\n"
    "  : $superclass$()",
    "classname", classname_,
    "superclass", superclass,
    "full_name", descriptor_->full_name());
  if (UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(
        ",\n    _internal_metadata_(NULL)");
  } else if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
    printer->Print(",\n    _arena_ptr_(NULL)");
  }
  if (IsAnyMessage(descriptor_)) {
    printer->Print(",\n    _any_metadata_(&type_url_, &value_)");
  }
  printer->Print(" {\n");
  printer->Print(
    "  SharedCtor();\n"
    "  MergeFrom(from);\n"
    "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
    "}\n"
    "\n",
    "classname", classname_,
    "superclass", superclass,
    "full_name", descriptor_->full_name());

  // Generate the shared constructor code.
  GenerateSharedConstructorCode(printer);

  // Generate the destructor.
  printer->Print(
    "$classname$::~$classname$() {\n"
    "  // @@protoc_insertion_point(destructor:$full_name$)\n"
    "  SharedDtor();\n"
    "}\n"
    "\n",
    "classname", classname_,
    "full_name", descriptor_->full_name());

  // Generate the shared destructor code.
  GenerateSharedDestructorCode(printer);

  // Generate the arena-specific destructor code.
  if (SupportsArenas(descriptor_)) {
    GenerateArenaDestructorCode(printer);
  }

  // Generate SetCachedSize.
  printer->Print(
    "void $classname$::SetCachedSize(int size) const {\n"
    "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
    "  _cached_size_ = size;\n"
    "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
    "}\n",
    "classname", classname_);

  // Only generate this member if it's not disabled.
  if (HasDescriptorMethods(descriptor_->file(), options_) &&
      !descriptor_->options().no_standard_descriptor_accessor()) {
    printer->Print(
      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
      "  protobuf_AssignDescriptorsOnce();\n"
      "  return $classname$_descriptor_;\n"
      "}\n"
      "\n",
      "classname", classname_,
      "adddescriptorsname",
      GlobalAddDescriptorsName(descriptor_->file()->name()));
  }

  printer->Print(
    "const $classname$& $classname$::default_instance() {\n",
    "classname", classname_);

  PrintHandlingOptionalStaticInitializers(
      descriptor_->file(), options_, printer,
      // With static initializers.
      "  if (default_instance_ == NULL) $adddescriptorsname$();\n",
      // Without.
      "  $adddescriptorsname$();\n",
      // Vars.
      "adddescriptorsname",
      GlobalAddDescriptorsName(descriptor_->file()->name()));

  printer->Print(
    "  return *default_instance_;\n"
    "}\n"
    "\n"
    "$classname$* $classname$::default_instance_ = NULL;\n"
    "\n",
    "classname", classname_);

  if (SupportsArenas(descriptor_)) {
    printer->Print(
      "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n"
      "  return ::google::protobuf::Arena::CreateMessage<$classname$>(arena);\n"
      "}\n",
      "classname", classname_);
  } else {
    printer->Print(
      "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n"
      "  $classname$* n = new $classname$;\n"
      "  if (arena != NULL) {\n"
      "    arena->Own(n);\n"
      "  }\n"
      "  return n;\n"
      "}\n",
      "classname", classname_);
  }

}

// Return the number of bits set in n, a non-negative integer.
static int popcnt(uint32 n) {
  int result = 0;
  while (n != 0) {
    result += (n & 1);
    n = n / 2;
  }
  return result;
}

void MessageGenerator::
GenerateClear(io::Printer* printer) {
  printer->Print(
      "void $classname$::Clear() {\n"
      "// @@protoc_insertion_point(message_clear_start:$full_name$)\n",
      "classname", classname_, "full_name", descriptor_->full_name());
  printer->Indent();

  // Step 1: Extensions
  if (descriptor_->extension_range_count() > 0) {
    printer->Print("_extensions_.Clear();\n");
  }

  // Step 2: Everything but extensions, repeateds, unions.
  // These are handled in chunks of 8.  The first chunk is
  // the non-extensions-non-repeateds-non-unions in
  //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
  // and the second chunk is the same for
  //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
  // etc.
  set<int> step2_indices;
  hash_map<string, int> fieldname_to_chunk;
  hash_map<int, string> memsets_for_chunk;
  hash_map<int, int> memset_field_count_for_chunk;
  hash_set<string> handled;  // fields that appear anywhere in memsets_for_chunk
  hash_map<int, uint32> fields_mask_for_chunk;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (!field->is_repeated() && !field->containing_oneof()) {
      step2_indices.insert(i);
      int chunk = i / 8;
      fieldname_to_chunk[FieldName(field)] = chunk;
      fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
    }
  }

  // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
  // The generated code uses two macros to help it clear runs of fields:
  // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the
  // positions of two fields in the Message.
  // ZR_ zeroes a non-empty range of fields via memset.
  const char* macros =
      "#if defined(__clang__)\n"
      "#define ZR_HELPER_(f) \\\n"
      "  _Pragma(\"clang diagnostic push\") \\\n"
      "  _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
      "  __builtin_offsetof($classname$, f) \\\n"
      "  _Pragma(\"clang diagnostic pop\")\n"
      "#else\n"
      "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
      "  &reinterpret_cast<$classname$*>(16)->f)\n"
      "#endif\n\n"
      "#define ZR_(first, last) do {\\\n"
      "  ::memset(&(first), 0,\\\n"
      "           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
      "} while (0)\n\n";
  for (int i = 0; i < runs_of_fields_.size(); i++) {
    const vector<string>& run = runs_of_fields_[i];
    if (run.size() < 2) continue;
    const string& first_field_name = run[0];
    const string& last_field_name = run.back();
    int chunk = fieldname_to_chunk[run[0]];
    memsets_for_chunk[chunk].append(
      "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
    for (int j = 0; j < run.size(); j++) {
      GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
      handled.insert(run[j]);
    }
    memset_field_count_for_chunk[chunk] += run.size();
  }
  const bool macros_are_needed = handled.size() > 0;
  if (macros_are_needed) {
    printer->Outdent();
    printer->Print(macros,
                   "classname", classname_);
    printer->Indent();
  }
  // Step 2b: Finish step 2, ignoring fields handled in step 2a.
  int last_index = -1;
  bool chunk_block_in_progress = false;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (step2_indices.count(i) == 0) continue;
    const FieldDescriptor* field = descriptor_->field(i);
    const string fieldname = FieldName(field);
    if (i / 8 != last_index / 8 || last_index < 0) {
      // End previous chunk, if there was one.
      if (chunk_block_in_progress) {
        printer->Outdent();
        printer->Print("}\n");
        chunk_block_in_progress = false;
      }
      // Start chunk.
      const string& memsets = memsets_for_chunk[i / 8];
      uint32 mask = fields_mask_for_chunk[i / 8];
      int count = popcnt(mask);
      GOOGLE_DCHECK_GE(count, 1);
      if (count == 1 ||
          (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
        // No "if" here because the chunk is trivial.
      } else {
        if (HasFieldPresence(descriptor_->file())) {
          printer->Print(
            "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
            "index", SimpleItoa(i / 8 * 8),
            "mask", SimpleItoa(mask));
          printer->Indent();
          chunk_block_in_progress = true;
        }
      }
      printer->Print(memsets.c_str());
    }
    last_index = i;
    if (handled.count(fieldname) > 0) continue;

    // It's faster to just overwrite primitive types, but we should
    // only clear strings and messages if they were set.
    // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
    bool should_check_bit =
      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
      field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;

    bool have_enclosing_if = false;
    if (should_check_bit &&
        // If no field presence, then always clear strings/messages as well.
        HasFieldPresence(descriptor_->file())) {
      printer->Print("if (has_$name$()) {\n", "name", fieldname);
      printer->Indent();
      have_enclosing_if = true;
    }

    if (use_dependent_base_ && IsFieldDependent(field)) {
      printer->Print("clear_$name$();\n", "name", fieldname);
    } else {
      field_generators_.get(field).GenerateClearingCode(printer);
    }

    if (have_enclosing_if) {
      printer->Outdent();
      printer->Print("}\n");
    }
  }

  if (chunk_block_in_progress) {
    printer->Outdent();
    printer->Print("}\n");
  }
  if (macros_are_needed) {
    printer->Outdent();
    printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n");
    printer->Indent();
  }

  // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    if (field->is_repeated()) {
      if (use_dependent_base_ && IsFieldDependent(field)) {
        printer->Print("clear_$name$();\n", "name", FieldName(field));
      } else {
        field_generators_.get(field).GenerateClearingCode(printer);
      }
    }
  }

  // Step 4: Unions.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "clear_$oneof_name$();\n",
        "oneof_name", descriptor_->oneof_decl(i)->name());
  }

  if (HasFieldPresence(descriptor_->file())) {
    // Step 5: Everything else.
    printer->Print(
      "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
  }

  if (PreserveUnknownFields(descriptor_)) {
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
        "if (_internal_metadata_.have_unknown_fields()) {\n"
        "  mutable_unknown_fields()->Clear();\n"
        "}\n");
    } else {
      if (SupportsArenas(descriptor_)) {
        printer->Print(
          "_unknown_fields_.ClearToEmpty(\n"
          "    &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
          "    GetArenaNoVirtual());\n");
      } else {
        printer->Print(
          "_unknown_fields_.ClearToEmptyNoArena(\n"
          "    &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
      }
    }
  }

  printer->Outdent();
  printer->Print("}\n");
}

void MessageGenerator::
GenerateOneofClear(io::Printer* printer) {
  // Generated function clears the active field and union case (e.g. foo_case_).
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    map<string, string> oneof_vars;
    oneof_vars["classname"] = classname_;
    oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
    oneof_vars["full_name"] = descriptor_->full_name();
    string message_class;

    printer->Print(oneof_vars,
                   "void $classname$::clear_$oneofname$() {\n"
                   "// @@protoc_insertion_point(one_of_clear_start:"
                   "$full_name$)\n");
    printer->Indent();
    printer->Print(oneof_vars,
        "switch($oneofname$_case()) {\n");
    printer->Indent();
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
      printer->Print(
          "case k$field_name$: {\n",
          "field_name", UnderscoresToCamelCase(field->name(), true));
      printer->Indent();
      // We clear only allocated objects in oneofs
      if (!IsStringOrMessage(field)) {
        printer->Print(
            "// No need to clear\n");
      } else {
        field_generators_.get(field).GenerateClearingCode(printer);
      }
      printer->Print(
          "break;\n");
      printer->Outdent();
      printer->Print(
          "}\n");
    }
    printer->Print(
        "case $cap_oneof_name$_NOT_SET: {\n"
        "  break;\n"
        "}\n",
        "cap_oneof_name",
        ToUpper(descriptor_->oneof_decl(i)->name()));
    printer->Outdent();
    printer->Print(
        "}\n"
        "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
        "oneof_index", SimpleItoa(i),
        "cap_oneof_name",
        ToUpper(descriptor_->oneof_decl(i)->name()));
    printer->Outdent();
    printer->Print(
        "}\n"
        "\n");
  }
}

void MessageGenerator::
GenerateSwap(io::Printer* printer) {
  if (SupportsArenas(descriptor_)) {
    // Generate the Swap member function. This is a lightweight wrapper around
    // UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory
    // ownership situation: swapping across arenas or between an arena and a
    // heap requires copying.
    printer->Print(
        "void $classname$::Swap($classname$* other) {\n"
        "  if (other == this) return;\n"
        "  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
        "    InternalSwap(other);\n"
        "  } else {\n"
        "    $classname$ temp;\n"
        "    temp.MergeFrom(*this);\n"
        "    CopyFrom(*other);\n"
        "    other->CopyFrom(temp);\n"
        "  }\n"
        "}\n"
        "void $classname$::UnsafeArenaSwap($classname$* other) {\n"
        "  if (other == this) return;\n"
        "  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
        "  InternalSwap(other);\n"
        "}\n",
        "classname", classname_);
  } else {
    printer->Print(
        "void $classname$::Swap($classname$* other) {\n"
        "  if (other == this) return;\n"
        "  InternalSwap(other);\n"
        "}\n",
        "classname", classname_);
  }

  // Generate the UnsafeArenaSwap member function.
  printer->Print("void $classname$::InternalSwap($classname$* other) {\n",
                 "classname", classname_);
  printer->Indent();

  if (HasGeneratedMethods(descriptor_->file(), options_)) {
    for (int i = 0; i < descriptor_->field_count(); i++) {
      const FieldDescriptor* field = descriptor_->field(i);
      field_generators_.get(field).GenerateSwappingCode(printer);
    }

    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
      printer->Print(
        "std::swap($oneof_name$_, other->$oneof_name$_);\n"
        "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
        "oneof_name", descriptor_->oneof_decl(i)->name(),
        "i", SimpleItoa(i));
    }

    if (HasFieldPresence(descriptor_->file())) {
      for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
        printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
                       "i", SimpleItoa(i));
      }
    }

    // Ignore PreserveUnknownFields here - always swap internal_metadata as it
    // may contain more than just unknown fields.
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
          "_internal_metadata_.Swap(&other->_internal_metadata_);\n");
    } else {
      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
    }

    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
    if (descriptor_->extension_range_count() > 0) {
      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
    }
  } else {
    printer->Print("GetReflection()->Swap(this, other);");
  }

  printer->Outdent();
  printer->Print("}\n");
}

void MessageGenerator::
GenerateMergeFrom(io::Printer* printer) {
  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    // Generate the generalized MergeFrom (aka that which takes in the Message
    // base class as a parameter).
    printer->Print(
        "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
        "// @@protoc_insertion_point(generalized_merge_from_start:"
        "$full_name$)\n"
        "  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
        "classname", classname_, "full_name", descriptor_->full_name());
    printer->Indent();

    // Cast the message to the proper type. If we find that the message is
    // *not* of the proper type, we can still call Merge via the reflection
    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
    // for each message.
    printer->Print(
      "const $classname$* source = \n"
      "    ::google::protobuf::internal::DynamicCastToGenerated<const $classname$>(\n"
      "        &from);\n"
      "if (source == NULL) {\n"
      "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
      "$full_name$)\n"
      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
      "} else {\n"
      "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
      "$full_name$)\n"
      "  MergeFrom(*source);\n"
      "}\n",
      "classname", classname_, "full_name", descriptor_->full_name());

    printer->Outdent();
    printer->Print("}\n\n");
  } else {
    // Generate CheckTypeAndMergeFrom().
    printer->Print(
      "void $classname$::CheckTypeAndMergeFrom(\n"
      "    const ::google::protobuf::MessageLite& from) {\n"
      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
      "}\n"
      "\n",
      "classname", classname_);
  }

  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
  printer->Print(
      "void $classname$::MergeFrom(const $classname$& from) {\n"
      "// @@protoc_insertion_point(class_specific_merge_from_start:"
      "$full_name$)\n"
      "  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
      "classname", classname_, "full_name", descriptor_->full_name());
  printer->Indent();

  // Merge Repeated fields. These fields do not require a
  // check as we can simply iterate over them.
  for (int i = 0; i < descriptor_->field_count(); ++i) {
    const FieldDescriptor* field = descriptor_->field(i);

    if (field->is_repeated()) {
      field_generators_.get(field).GenerateMergingCode(printer);
    }
  }

  // Merge oneof fields. Oneof field requires oneof case check.
  for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
    printer->Print(
        "switch (from.$oneofname$_case()) {\n",
        "oneofname", descriptor_->oneof_decl(i)->name());
    printer->Indent();
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
      printer->Print(
          "case k$field_name$: {\n",
          "field_name", UnderscoresToCamelCase(field->name(), true));
      printer->Indent();
      field_generators_.get(field).GenerateMergingCode(printer);
      printer->Print(
          "break;\n");
      printer->Outdent();
      printer->Print(
          "}\n");
    }
    printer->Print(
        "case $cap_oneof_name$_NOT_SET: {\n"
        "  break;\n"
        "}\n",
        "cap_oneof_name",
        ToUpper(descriptor_->oneof_decl(i)->name()));
    printer->Outdent();
    printer->Print(
        "}\n");
  }

  // Merge Optional and Required fields (after a _has_bit check).
  int last_index = -1;

  for (int i = 0; i < descriptor_->field_count(); ++i) {
    const FieldDescriptor* field = descriptor_->field(i);

    if (!field->is_repeated() && !field->containing_oneof()) {
      if (HasFieldPresence(descriptor_->file())) {
        // See above in GenerateClear for an explanation of this.
        if (i / 8 != last_index / 8 || last_index < 0) {
          if (last_index >= 0) {
            printer->Outdent();
            printer->Print("}\n");
          }
          printer->Print(
            "if (from._has_bits_[$index$ / 32] & "
            "(0xffu << ($index$ % 32))) {\n",
            "index", SimpleItoa(field->index()));
          printer->Indent();
        }
      }

      last_index = i;

      bool have_enclosing_if = false;
      if (HasFieldPresence(descriptor_->file())) {
        printer->Print(
          "if (from.has_$name$()) {\n",
          "name", FieldName(field));
        printer->Indent();
        have_enclosing_if = true;
      } else {
        // Merge semantics without true field presence: primitive fields are
        // merged only if non-zero (numeric) or non-empty (string).
        have_enclosing_if = EmitFieldNonDefaultCondition(
            printer, "from.", field);
      }

      field_generators_.get(field).GenerateMergingCode(printer);

      if (have_enclosing_if) {
        printer->Outdent();
        printer->Print("}\n");
      }
    }
  }

  if (HasFieldPresence(descriptor_->file()) &&
      last_index >= 0) {
    printer->Outdent();
    printer->Print("}\n");
  }

  if (descriptor_->extension_range_count() > 0) {
    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
  }

  if (PreserveUnknownFields(descriptor_)) {
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
        "if (from._internal_metadata_.have_unknown_fields()) {\n"
        "  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"
        "}\n");
    } else {
      printer->Print(
        "if (!from.unknown_fields().empty()) {\n"
        "  mutable_unknown_fields()->append(from.unknown_fields());\n"
        "}\n");
    }
  }

  printer->Outdent();
  printer->Print("}\n");
}

void MessageGenerator::
GenerateCopyFrom(io::Printer* printer) {
  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    // Generate the generalized CopyFrom (aka that which takes in the Message
    // base class as a parameter).
    printer->Print(
        "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n"
        "// @@protoc_insertion_point(generalized_copy_from_start:"
        "$full_name$)\n",
        "classname", classname_, "full_name", descriptor_->full_name());
    printer->Indent();

    printer->Print(
      "if (&from == this) return;\n"
      "Clear();\n"
      "MergeFrom(from);\n");

    printer->Outdent();
    printer->Print("}\n\n");
  }

  // Generate the class-specific CopyFrom.
  printer->Print(
      "void $classname$::CopyFrom(const $classname$& from) {\n"
      "// @@protoc_insertion_point(class_specific_copy_from_start:"
      "$full_name$)\n",
      "classname", classname_, "full_name", descriptor_->full_name());
  printer->Indent();

  printer->Print(
    "if (&from == this) return;\n"
    "Clear();\n"
    "MergeFrom(from);\n");

  printer->Outdent();
  printer->Print("}\n");
}

void MessageGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) {
  if (descriptor_->options().message_set_wire_format()) {
    // Special-case MessageSet.
    printer->Print(
      "bool $classname$::MergePartialFromCodedStream(\n"
      "    ::google::protobuf::io::CodedInputStream* input) {\n",
      "classname", classname_);

    PrintHandlingOptionalStaticInitializers(
        descriptor_->file(), options_, printer,
        // With static initializers.
        "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
        "                                      mutable_unknown_fields());\n",
        // Without.
        "  return _extensions_.ParseMessageSet(input, &default_instance(),\n"
        "                                      mutable_unknown_fields());\n",
        // Vars.
        "classname", classname_);

    printer->Print(
      "}\n");
    return;
  }

  printer->Print(
    "bool $classname$::MergePartialFromCodedStream(\n"
    "    ::google::protobuf::io::CodedInputStream* input) {\n"
    "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n"
    "  ::google::protobuf::uint32 tag;\n",
    "classname", classname_);

  if (PreserveUnknownFields(descriptor_) &&
      !UseUnknownFieldSet(descriptor_->file(), options_)) {
    // Use LazyStringOutputString to avoid initializing unknown fields string
    // unless it is actually needed. For the same reason, disable eager refresh
    // on the CodedOutputStream.
    printer->Print(
      "  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
      "      ::google::protobuf::internal::NewPermanentCallback(\n"
      "          &MutableUnknownFieldsFor$classname$, this));\n"
      "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
      "      &unknown_fields_string, false);\n",
      "classname", classname_);
  }

  printer->Print(
    "  // @@protoc_insertion_point(parse_start:$full_name$)\n",
    "full_name", descriptor_->full_name());

  printer->Indent();
  printer->Print("for (;;) {\n");
  printer->Indent();

  google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
      SortFieldsByNumber(descriptor_));
  uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
      WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
  const int kCutoff0 = 127;               // fits in 1-byte varint
  const int kCutoff1 = (127 << 7) + 127;  // fits in 2-byte varint
  printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
                 "input->ReadTagWithCutoff($max$);\n"
                 "tag = p.first;\n"
                 "if (!p.second) goto handle_unusual;\n",
                 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
                                   (maxtag <= kCutoff1 ? kCutoff1 :
                                    maxtag)));
  if (descriptor_->field_count() > 0) {
    // We don't even want to print the switch() if we have no fields because
    // MSVC dislikes switch() statements that contain only a default value.

    // Note:  If we just switched on the tag rather than the field number, we
    // could avoid the need for the if() to check the wire type at the beginning
    // of each case.  However, this is actually a bit slower in practice as it
    // creates a jump table that is 8x larger and sparser, and meanwhile the
    // if()s are highly predictable.
    printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
                   "GetTagFieldNumber(tag)) {\n");

    printer->Indent();

    // Find repeated messages and groups now, to simplify what follows.
    hash_set<int> fields_with_parse_loop;
    for (int i = 0; i < descriptor_->field_count(); i++) {
      const FieldDescriptor* field = ordered_fields[i];
      if (field->is_repeated() &&
          (field->type() == FieldDescriptor::TYPE_MESSAGE ||
           field->type() == FieldDescriptor::TYPE_GROUP)) {
        fields_with_parse_loop.insert(i);
      }
    }

    // need_label is true if we generated "goto parse_$name$" while handling the
    // previous field.
    bool need_label = false;
    for (int i = 0; i < descriptor_->field_count(); i++) {
      const FieldDescriptor* field = ordered_fields[i];
      const bool loops = fields_with_parse_loop.count(i) > 0;
      const bool next_field_loops = fields_with_parse_loop.count(i + 1) > 0;

      PrintFieldComment(printer, field);

      printer->Print(
        "case $number$: {\n",
        "number", SimpleItoa(field->number()));
      printer->Indent();
      const FieldGenerator& field_generator = field_generators_.get(field);

      // Emit code to parse the common, expected case.
      printer->Print("if (tag == $commontag$) {\n",
                     "commontag", SimpleItoa(WireFormat::MakeTag(field)));

      if (need_label ||
          (field->is_repeated() && !field->is_packed() && !loops)) {
        printer->Print(
            " parse_$name$:\n",
            "name", field->name());
      }
      if (loops) {
        printer->Print(
          "  DO_(input->IncrementRecursionDepth());\n"
          " parse_loop_$name$:\n",
          "name", field->name());
      }

      printer->Indent();
      if (field->is_packed()) {
        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
      } else {
        field_generator.GenerateMergeFromCodedStream(printer);
      }
      printer->Outdent();

      // Emit code to parse unexpectedly packed or unpacked values.
      if (field->is_packed()) {
        internal::WireFormatLite::WireType wiretype =
            WireFormat::WireTypeForFieldType(field->type());
        printer->Print("} else if (tag == $uncommontag$) {\n",
                       "uncommontag", SimpleItoa(
                           internal::WireFormatLite::MakeTag(
                               field->number(), wiretype)));
        printer->Indent();
        field_generator.GenerateMergeFromCodedStream(printer);
        printer->Outdent();
      } else if (field->is_packable() && !field->is_packed()) {
        internal::WireFormatLite::WireType wiretype =
            internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
        printer->Print("} else if (tag == $uncommontag$) {\n",
                       "uncommontag", SimpleItoa(
                           internal::WireFormatLite::MakeTag(
                               field->number(), wiretype)));
        printer->Indent();
        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
        printer->Outdent();
      }

      printer->Print(
        "} else {\n"
        "  goto handle_unusual;\n"
        "}\n");

      // switch() is slow since it can't be predicted well.  Insert some if()s
      // here that attempt to predict the next tag.
      // For non-packed repeated fields, expect the same tag again.
      if (loops) {
        printer->Print(
          "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n",
          "tag", SimpleItoa(WireFormat::MakeTag(field)),
          "name", field->name());
      } else if (field->is_repeated() && !field->is_packed()) {
        printer->Print(
          "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
          "tag", SimpleItoa(WireFormat::MakeTag(field)),
          "name", field->name());
      }

      // Have we emitted "if (input->ExpectTag($next_tag$)) ..." yet?
      bool emitted_goto_next_tag = false;

      // For repeated messages/groups, we need to decrement recursion depth,
      // unless the next tag is also for a repeated message/group.
      if (loops) {
        if (next_field_loops) {
          const FieldDescriptor* next_field = ordered_fields[i + 1];
          printer->Print(
            "if (input->ExpectTag($next_tag$)) goto parse_loop_$next_name$;\n",
            "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
            "next_name", next_field->name());
          emitted_goto_next_tag = true;
        }
        printer->Print(
          "input->UnsafeDecrementRecursionDepth();\n");
      }

      // If there are more fields, expect the next one.
      need_label = false;
      if (!emitted_goto_next_tag) {
        if (i + 1 == descriptor_->field_count()) {
          // Expect EOF.
          // TODO(kenton):  Expect group end-tag?
          printer->Print(
            "if (input->ExpectAtEnd()) goto success;\n");
        } else {
          const FieldDescriptor* next_field = ordered_fields[i + 1];
          printer->Print(
            "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
            "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
            "next_name", next_field->name());
          need_label = true;
        }
      }

      printer->Print(
        "break;\n");

      printer->Outdent();
      printer->Print("}\n\n");
    }

    printer->Print("default: {\n");
    printer->Indent();
  }

  printer->Outdent();
  printer->Print("handle_unusual:\n");
  printer->Indent();
  // If tag is 0 or an end-group tag then this must be the end of the message.
  printer->Print(
    "if (tag == 0 ||\n"
    "    ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
    "  goto success;\n"
    "}\n");

  // Handle extension ranges.
  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
      "if (");
    for (int i = 0; i < descriptor_->extension_range_count(); i++) {
      const Descriptor::ExtensionRange* range =
        descriptor_->extension_range(i);
      if (i > 0) printer->Print(" ||\n    ");

      uint32 start_tag = WireFormatLite::MakeTag(
        range->start, static_cast<WireFormatLite::WireType>(0));
      uint32 end_tag = WireFormatLite::MakeTag(
        range->end, static_cast<WireFormatLite::WireType>(0));

      if (range->end > FieldDescriptor::kMaxNumber) {
        printer->Print(
          "($start$u <= tag)",
          "start", SimpleItoa(start_tag));
      } else {
        printer->Print(
          "($start$u <= tag && tag < $end$u)",
          "start", SimpleItoa(start_tag),
          "end", SimpleItoa(end_tag));
      }
    }
    printer->Print(") {\n");
    if (PreserveUnknownFields(descriptor_)) {
      if (UseUnknownFieldSet(descriptor_->file(), options_)) {
        PrintHandlingOptionalStaticInitializers(
            descriptor_->file(), options_, printer,
            // With static initializers.
            "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
            "                              mutable_unknown_fields()));\n",
            // Without.
            "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
            "                              mutable_unknown_fields()));\n");
      } else {
        PrintHandlingOptionalStaticInitializers(
            descriptor_->file(), options_, printer,
            // With static initializers.
            "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
            "                              &unknown_fields_stream));\n",
            // Without.
            "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
            "                              &unknown_fields_stream));\n");
      }
    } else {
      PrintHandlingOptionalStaticInitializers(
          descriptor_->file(), options_, printer,
          // With static initializers.
          "  DO_(_extensions_.ParseField(tag, input, default_instance_);\n",
          // Without.
          "  DO_(_extensions_.ParseField(tag, input, &default_instance());\n");
    }
    printer->Print(
      "  continue;\n"
      "}\n");
  }

  // We really don't recognize this tag.  Skip it.
  if (PreserveUnknownFields(descriptor_)) {
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
        "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
        "      input, tag, mutable_unknown_fields()));\n");
    } else {
      printer->Print(
        "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
        "    input, tag, &unknown_fields_stream));\n");
    }
  } else {
    printer->Print(
      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
  }

  if (descriptor_->field_count() > 0) {
    printer->Print("break;\n");
    printer->Outdent();
    printer->Print("}\n");    // default:
    printer->Outdent();
    printer->Print("}\n");    // switch
  }

  printer->Outdent();
  printer->Outdent();
  printer->Print(
    "  }\n"                   // for (;;)
    "success:\n"
    "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
    "  return true;\n"
    "failure:\n"
    "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
    "  return false;\n"
    "#undef DO_\n"
    "}\n", "full_name", descriptor_->full_name());
}

void MessageGenerator::GenerateSerializeOneField(
    io::Printer* printer, const FieldDescriptor* field, bool to_array) {
  PrintFieldComment(printer, field);

  bool have_enclosing_if = false;
  if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) {
    printer->Print(
      "if (has_$name$()) {\n",
      "name", FieldName(field));
    printer->Indent();
    have_enclosing_if = true;
  } else if (!HasFieldPresence(descriptor_->file())) {
    have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
  }

  if (to_array) {
    field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
        printer);
  } else {
    field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
  }

  if (have_enclosing_if) {
    printer->Outdent();
    printer->Print("}\n");
  }
  printer->Print("\n");
}

void MessageGenerator::GenerateSerializeOneExtensionRange(
    io::Printer* printer, const Descriptor::ExtensionRange* range,
    bool to_array) {
  map<string, string> vars;
  vars["start"] = SimpleItoa(range->start);
  vars["end"] = SimpleItoa(range->end);
  printer->Print(vars,
    "// Extension range [$start$, $end$)\n");
  if (to_array) {
    printer->Print(vars,
      "target = _extensions_.SerializeWithCachedSizesToArray(\n"
      "    $start$, $end$, target);\n\n");
  } else {
    printer->Print(vars,
      "_extensions_.SerializeWithCachedSizes(\n"
      "    $start$, $end$, output);\n\n");
  }
}

void MessageGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) {
  if (descriptor_->options().message_set_wire_format()) {
    // Special-case MessageSet.
    printer->Print(
      "void $classname$::SerializeWithCachedSizes(\n"
      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
      "classname", classname_);
    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
    printer->Print(
      "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
      "      unknown_fields(), output);\n");
    printer->Print(
      "}\n");
    return;
  }

  printer->Print(
    "void $classname$::SerializeWithCachedSizes(\n"
    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
    "classname", classname_);
  printer->Indent();

  printer->Print(
    "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
    "full_name", descriptor_->full_name());

  GenerateSerializeWithCachedSizesBody(printer, false);

  printer->Print(
    "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
    "full_name", descriptor_->full_name());

  printer->Outdent();
  printer->Print(
    "}\n");
}

void MessageGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
  if (descriptor_->options().message_set_wire_format()) {
    // Special-case MessageSet.
    printer->Print(
      "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
      "    ::google::protobuf::uint8* target) const {\n"
      "  target =\n"
      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
      "classname", classname_);
    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
    printer->Print(
      "  target = ::google::protobuf::internal::WireFormat::\n"
      "             SerializeUnknownMessageSetItemsToArray(\n"
      "               unknown_fields(), target);\n");
    printer->Print(
      "  return target;\n"
      "}\n");
    return;
  }

  printer->Print(
    "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
    "    ::google::protobuf::uint8* target) const {\n",
    "classname", classname_);
  printer->Indent();

  printer->Print(
    "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
    "full_name", descriptor_->full_name());

  GenerateSerializeWithCachedSizesBody(printer, true);

  printer->Print(
    "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
    "full_name", descriptor_->full_name());

  printer->Outdent();
  printer->Print(
    "  return target;\n"
    "}\n");
}

void MessageGenerator::
GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
  google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
      SortFieldsByNumber(descriptor_));

  vector<const Descriptor::ExtensionRange*> sorted_extensions;
  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
    sorted_extensions.push_back(descriptor_->extension_range(i));
  }
  std::sort(sorted_extensions.begin(), sorted_extensions.end(),
            ExtensionRangeSorter());

  // Merge the fields and the extension ranges, both sorted by field number.
  int i, j;
  for (i = 0, j = 0;
       i < descriptor_->field_count() || j < sorted_extensions.size();
       ) {
    if (i == descriptor_->field_count()) {
      GenerateSerializeOneExtensionRange(printer,
                                         sorted_extensions[j++],
                                         to_array);
    } else if (j == sorted_extensions.size()) {
      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
    } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
    } else {
      GenerateSerializeOneExtensionRange(printer,
                                         sorted_extensions[j++],
                                         to_array);
    }
  }

  if (PreserveUnknownFields(descriptor_)) {
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n");
      printer->Indent();
      if (to_array) {
        printer->Print(
          "target = "
              "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
          "    unknown_fields(), target);\n");
      } else {
        printer->Print(
          "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
          "    unknown_fields(), output);\n");
      }
      printer->Outdent();

      printer->Print(
        "}\n");
    } else {
      printer->Print(
        "output->WriteRaw(unknown_fields().data(),\n"
        "                 static_cast<int>(unknown_fields().size()));\n");
    }
  }
}

static vector<uint32> RequiredFieldsBitMask(const Descriptor* desc) {
  vector<uint32> result;
  uint32 mask = 0;
  for (int i = 0; i < desc->field_count(); i++) {
    if (i > 0 && i % 32 == 0) {
      result.push_back(mask);
      mask = 0;
    }
    if (desc->field(i)->is_required()) {
      mask |= (1 << (i & 31));
    }
  }
  if (mask != 0) {
    result.push_back(mask);
  }
  return result;
}

// Create an expression that evaluates to
//  "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
// masks is allowed to be shorter than _has_bits_, but at least one element of
// masks must be non-zero.
static string ConditionalToCheckBitmasks(const vector<uint32>& masks) {
  vector<string> parts;
  for (int i = 0; i < masks.size(); i++) {
    if (masks[i] == 0) continue;
    string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
    // Each xor evaluates to 0 if the expected bits are present.
    parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
  }
  GOOGLE_CHECK(!parts.empty());
  // If we have multiple parts, each expected to be 0, then bitwise-or them.
  string result = parts.size() == 1 ? parts[0] :
      StrCat("(", Join(parts, "\n       | "), ")");
  return result + " == 0";
}

void MessageGenerator::
GenerateByteSize(io::Printer* printer) {
  if (descriptor_->options().message_set_wire_format()) {
    // Special-case MessageSet.
    printer->Print(
        "int $classname$::ByteSize() const {\n"
        "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
        "  int total_size = _extensions_.MessageSetByteSize();\n",
        "classname", classname_, "full_name", descriptor_->full_name());
    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
    printer->Print(
      "if (_internal_metadata_.have_unknown_fields()) {\n"
      "  total_size += ::google::protobuf::internal::WireFormat::\n"
      "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n"
      "}\n");
    printer->Print(
      "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
      "  _cached_size_ = total_size;\n"
      "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
      "  return total_size;\n"
      "}\n");
    return;
  }

  if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
    // Emit a function (rarely used, we hope) that handles the required fields
    // by checking for each one individually.
    printer->Print(
        "int $classname$::RequiredFieldsByteSizeFallback() const {\n"
        "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
        "$full_name$)\n",
        "classname", classname_, "full_name", descriptor_->full_name());
    printer->Indent();
    printer->Print("int total_size = 0;\n");
    for (int i = 0; i < descriptor_->field_count(); i++) {
      const FieldDescriptor* field = descriptor_->field(i);
      if (field->is_required()) {
        printer->Print("\n"
                       "if (has_$name$()) {\n",
                       "name", FieldName(field));
        printer->Indent();
        PrintFieldComment(printer, field);
        field_generators_.get(field).GenerateByteSize(printer);
        printer->Outdent();
        printer->Print("}\n");
      }
    }
    printer->Print("\n"
                   "return total_size;\n");
    printer->Outdent();
    printer->Print("}\n");
  }

  printer->Print(
      "int $classname$::ByteSize() const {\n"
      "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n",
      "classname", classname_, "full_name", descriptor_->full_name());
  printer->Indent();
  printer->Print(
    "int total_size = 0;\n"
    "\n");

  // Handle required fields (if any).  We expect all of them to be
  // present, so emit one conditional that checks for that.  If they are all
  // present then the fast path executes; otherwise the slow path executes.
  if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
    // The fast path works if all required fields are present.
    vector<uint32> masks_for_has_bits = RequiredFieldsBitMask(descriptor_);
    printer->Print((string("if (") +
                    ConditionalToCheckBitmasks(masks_for_has_bits) +
                    ") {  // All required fields are present.\n").c_str());
    printer->Indent();
    for (int i = 0; i < descriptor_->field_count(); i++) {
      const FieldDescriptor* field = descriptor_->field(i);
      if (!field->is_required()) continue;
      PrintFieldComment(printer, field);
      field_generators_.get(field).GenerateByteSize(printer);
      printer->Print("\n");
    }
    printer->Outdent();
    printer->Print("} else {\n"  // the slow path
                   "  total_size += RequiredFieldsByteSizeFallback();\n"
                   "}\n");
  } else {
    // num_required_fields_ <= 1: no need to be tricky
    for (int i = 0; i < descriptor_->field_count(); i++) {
      const FieldDescriptor* field = descriptor_->field(i);
      if (!field->is_required()) continue;
      PrintFieldComment(printer, field);
      printer->Print("if (has_$name$()) {\n",
                     "name", FieldName(field));
      printer->Indent();
      field_generators_.get(field).GenerateByteSize(printer);
      printer->Outdent();
      printer->Print("}\n");
    }
  }

  // Handle optional fields (worry below about repeateds, oneofs, etc.).
  // These are handled in chunks of 8.  The first chunk is
  // the non-requireds-non-repeateds-non-unions-non-extensions in
  //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
  // and the second chunk is the same for
  //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
  // etc.
  hash_map<int, uint32> fields_mask_for_chunk;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (!field->is_required() && !field->is_repeated() &&
        !field->containing_oneof()) {
      fields_mask_for_chunk[i / 8] |= static_cast<uint32>(1) << (i % 32);
    }
  }

  int last_index = -1;
  bool chunk_block_in_progress = false;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (!field->is_required() && !field->is_repeated() &&
        !field->containing_oneof()) {
      // See above in GenerateClear for an explanation of this.
      // TODO(kenton):  Share code?  Unclear how to do so without
      //   over-engineering.
      if (i / 8 != last_index / 8 || last_index < 0) {
        // End previous chunk, if there was one.
        if (chunk_block_in_progress) {
          printer->Outdent();
          printer->Print("}\n");
          chunk_block_in_progress = false;
        }
        // Start chunk.
        uint32 mask = fields_mask_for_chunk[i / 8];
        int count = popcnt(mask);
        GOOGLE_DCHECK_GE(count, 1);
        if (count == 1) {
          // No "if" here because the chunk is trivial.
        } else {
          if (HasFieldPresence(descriptor_->file())) {
            printer->Print(
              "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
              "index", SimpleItoa(i),
              "mask", SimpleItoa(mask));
            printer->Indent();
            chunk_block_in_progress = true;
          }
        }
      }
      last_index = i;

      PrintFieldComment(printer, field);

      bool have_enclosing_if = false;
      if (HasFieldPresence(descriptor_->file())) {
        printer->Print(
          "if (has_$name$()) {\n",
          "name", FieldName(field));
        printer->Indent();
        have_enclosing_if = true;
      } else {
        // Without field presence: field is serialized only if it has a
        // non-default value.
        have_enclosing_if = EmitFieldNonDefaultCondition(
            printer, "this->", field);
      }

      field_generators_.get(field).GenerateByteSize(printer);

      if (have_enclosing_if) {
        printer->Outdent();
        printer->Print(
          "}\n"
          "\n");
      }
    }
  }

  if (chunk_block_in_progress) {
    printer->Outdent();
    printer->Print("}\n");
  }

  // Repeated fields don't use _has_bits_ so we count them in a separate
  // pass.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);

    if (field->is_repeated()) {
      PrintFieldComment(printer, field);
      field_generators_.get(field).GenerateByteSize(printer);
      printer->Print("\n");
    }
  }

  // Fields inside a oneof don't use _has_bits_ so we count them in a separate
  // pass.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
        "switch ($oneofname$_case()) {\n",
        "oneofname", descriptor_->oneof_decl(i)->name());
    printer->Indent();
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
      PrintFieldComment(printer, field);
      printer->Print(
          "case k$field_name$: {\n",
          "field_name", UnderscoresToCamelCase(field->name(), true));
      printer->Indent();
      field_generators_.get(field).GenerateByteSize(printer);
      printer->Print(
          "break;\n");
      printer->Outdent();
      printer->Print(
          "}\n");
    }
    printer->Print(
        "case $cap_oneof_name$_NOT_SET: {\n"
        "  break;\n"
        "}\n",
        "cap_oneof_name",
        ToUpper(descriptor_->oneof_decl(i)->name()));
    printer->Outdent();
    printer->Print(
        "}\n");
  }

  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
      "total_size += _extensions_.ByteSize();\n"
      "\n");
  }

  if (PreserveUnknownFields(descriptor_)) {
    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
      printer->Print(
        "if (_internal_metadata_.have_unknown_fields()) {\n"
        "  total_size +=\n"
        "    ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
        "      unknown_fields());\n"
        "}\n");
    } else {
      printer->Print(
        "total_size += unknown_fields().size();\n"
        "\n");
    }
  }

  // We update _cached_size_ even though this is a const method.  In theory,
  // this is not thread-compatible, because concurrent writes have undefined
  // results.  In practice, since any concurrent writes will be writing the
  // exact same value, it works on all common processors.  In a future version
  // of C++, _cached_size_ should be made into an atomic<int>.
  printer->Print(
    "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
    "_cached_size_ = total_size;\n"
    "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
    "return total_size;\n");

  printer->Outdent();
  printer->Print("}\n");
}

void MessageGenerator::
GenerateIsInitialized(io::Printer* printer) {
  printer->Print(
    "bool $classname$::IsInitialized() const {\n",
    "classname", classname_);
  printer->Indent();

  if (HasFieldPresence(descriptor_->file())) {
    // Check that all required fields in this message are set.  We can do this
    // most efficiently by checking 32 "has bits" at a time.
    int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
    for (int i = 0; i < has_bits_array_size; i++) {
      uint32 mask = 0;
      for (int bit = 0; bit < 32; bit++) {
        int index = i * 32 + bit;
        if (index >= descriptor_->field_count()) break;
        const FieldDescriptor* field = descriptor_->field(index);

        if (field->is_required()) {
          mask |= 1 << bit;
        }
      }

      if (mask != 0) {
        printer->Print(
          "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
          "i", SimpleItoa(i),
          "mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));
      }
    }
  }

  // Now check that all embedded messages are initialized.
  printer->Print("\n");
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
        !ShouldIgnoreRequiredFieldCheck(field, options_) &&
        HasRequiredFields(field->message_type(), options_)) {
      if (field->is_repeated()) {
        printer->Print(
          "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
          " return false;\n",
          "name", FieldName(field));
      } else {
        if (field->options().weak() || !field->containing_oneof()) {
          // For weak fields, use the data member (::google::protobuf::Message*) instead
          // of the getter to avoid a link dependency on the weak message type
          // which is only forward declared.
          printer->Print(
              "if (has_$name$()) {\n"
              "  if (!this->$name$_->IsInitialized()) return false;\n"
              "}\n",
            "name", FieldName(field));
        } else {
          printer->Print(
            "if (has_$name$()) {\n"
            "  if (!this->$name$().IsInitialized()) return false;\n"
            "}\n",
            "name", FieldName(field));
        }
      }
    }
  }

  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
      "\n"
      "if (!_extensions_.IsInitialized()) return false;");
  }

  printer->Outdent();
  printer->Print(
    "  return true;\n"
    "}\n");
}


}  // namespace cpp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
