// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/type.proto

#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include <google/protobuf/type.pb.h>

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)

namespace google {
namespace protobuf {
class TypeDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Type> {
} _Type_default_instance_;
class FieldDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Field> {
} _Field_default_instance_;
class EnumDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Enum> {
} _Enum_default_instance_;
class EnumValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<EnumValue> {
} _EnumValue_default_instance_;
class OptionDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Option> {
} _Option_default_instance_;

namespace protobuf_google_2fprotobuf_2ftype_2eproto {


namespace {

::google::protobuf::Metadata file_level_metadata[5];
const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[3];

}  // namespace

PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
    const TableStruct::entries[] = {
  {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
};

PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
    const TableStruct::aux[] = {
  ::google::protobuf::internal::AuxillaryParseTableField(),
};
PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
    TableStruct::schema[] = {
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
  { NULL, NULL, 0, -1, -1, false },
};

const ::google::protobuf::uint32 TableStruct::offsets[] = {
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, source_context_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, syntax_),
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, type_url_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, oneof_index_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, packed_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, json_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, default_value_),
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, source_context_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, syntax_),
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, number_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, options_),
  ~0u,  // no _has_bits_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, value_),
};

static const ::google::protobuf::internal::MigrationSchema schemas[] = {
  { 0, -1, sizeof(Type)},
  { 11, -1, sizeof(Field)},
  { 26, -1, sizeof(Enum)},
  { 36, -1, sizeof(EnumValue)},
  { 44, -1, sizeof(Option)},
};

static ::google::protobuf::Message const * const file_default_instances[] = {
  reinterpret_cast<const ::google::protobuf::Message*>(&_Type_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_Field_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_Enum_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_EnumValue_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&_Option_default_instance_),
};

namespace {

void protobuf_AssignDescriptors() {
  AddDescriptors();
  ::google::protobuf::MessageFactory* factory = NULL;
  AssignDescriptors(
      "google/protobuf/type.proto", schemas, file_default_instances, TableStruct::offsets, factory,
      file_level_metadata, file_level_enum_descriptors, NULL);
}

void protobuf_AssignDescriptorsOnce() {
  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
  ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
}

void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 5);
}

}  // namespace

void TableStruct::Shutdown() {
  _Type_default_instance_.Shutdown();
  delete file_level_metadata[0].reflection;
  _Field_default_instance_.Shutdown();
  delete file_level_metadata[1].reflection;
  _Enum_default_instance_.Shutdown();
  delete file_level_metadata[2].reflection;
  _EnumValue_default_instance_.Shutdown();
  delete file_level_metadata[3].reflection;
  _Option_default_instance_.Shutdown();
  delete file_level_metadata[4].reflection;
}

void TableStruct::InitDefaultsImpl() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::google::protobuf::internal::InitProtobufDefaults();
  ::google::protobuf::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaults();
  ::google::protobuf::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::InitDefaults();
  _Type_default_instance_.DefaultConstruct();
  _Field_default_instance_.DefaultConstruct();
  _Enum_default_instance_.DefaultConstruct();
  _EnumValue_default_instance_.DefaultConstruct();
  _Option_default_instance_.DefaultConstruct();
  _Type_default_instance_.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>(
      ::google::protobuf::SourceContext::internal_default_instance());
  _Enum_default_instance_.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>(
      ::google::protobuf::SourceContext::internal_default_instance());
  _Option_default_instance_.get_mutable()->value_ = const_cast< ::google::protobuf::Any*>(
      ::google::protobuf::Any::internal_default_instance());
}

void InitDefaults() {
  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
  ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
}
void AddDescriptorsImpl() {
  InitDefaults();
  static const char descriptor[] = {
      "\n\032google/protobuf/type.proto\022\017google.pro"
      "tobuf\032\031google/protobuf/any.proto\032$google"
      "/protobuf/source_context.proto\"\327\001\n\004Type\022"
      "\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
      "rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
      "\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
      "e_context\030\005 \001(\0132\036.google.protobuf.Source"
      "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
      "f.Syntax\"\325\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
      "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
      "(\0162\".google.protobuf.Field.Cardinality\022\016"
      "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
      "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
      "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
      "ption\022\021\n\tjson_name\030\n \001(\t\022\025\n\rdefault_valu"
      "e\030\013 \001(\t\"\310\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TY"
      "PE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT6"
      "4\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014"
      "TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE"
      "_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n"
      "\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TY"
      "PE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXE"
      "D32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020"
      "\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013Cardinality\022\027\n\023CAR"
      "DINALITY_UNKNOWN\020\000\022\030\n\024CARDINALITY_OPTION"
      "AL\020\001\022\030\n\024CARDINALITY_REQUIRED\020\002\022\030\n\024CARDIN"
      "ALITY_REPEATED\020\003\"\316\001\n\004Enum\022\014\n\004name\030\001 \001(\t\022"
      "-\n\tenumvalue\030\002 \003(\0132\032.google.protobuf.Enu"
      "mValue\022(\n\007options\030\003 \003(\0132\027.google.protobu"
      "f.Option\0226\n\016source_context\030\004 \001(\0132\036.googl"
      "e.protobuf.SourceContext\022\'\n\006syntax\030\005 \001(\016"
      "2\027.google.protobuf.Syntax\"S\n\tEnumValue\022\014"
      "\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\022(\n\007options\030"
      "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option"
      "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p"
      "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000"
      "\022\021\n\rSYNTAX_PROTO3\020\001B}\n\023com.google.protob"
      "ufB\tTypeProtoP\001Z/google.golang.org/genpr"
      "oto/protobuf/ptype;ptype\370\001\001\242\002\003GPB\252\002\036Goog"
      "le.Protobuf.WellKnownTypesb\006proto3"
  };
  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
      descriptor, 1594);
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "google/protobuf/type.proto", &protobuf_RegisterTypes);
  ::google::protobuf::protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptors();
  ::google::protobuf::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::AddDescriptors();
  ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown);
}

void AddDescriptors() {
  static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
  ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer {
  StaticDescriptorInitializer() {
    AddDescriptors();
  }
} static_descriptor_initializer;

}  // namespace protobuf_google_2fprotobuf_2ftype_2eproto

const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_enum_descriptors[0];
}
bool Field_Kind_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const Field_Kind Field::TYPE_UNKNOWN;
const Field_Kind Field::TYPE_DOUBLE;
const Field_Kind Field::TYPE_FLOAT;
const Field_Kind Field::TYPE_INT64;
const Field_Kind Field::TYPE_UINT64;
const Field_Kind Field::TYPE_INT32;
const Field_Kind Field::TYPE_FIXED64;
const Field_Kind Field::TYPE_FIXED32;
const Field_Kind Field::TYPE_BOOL;
const Field_Kind Field::TYPE_STRING;
const Field_Kind Field::TYPE_GROUP;
const Field_Kind Field::TYPE_MESSAGE;
const Field_Kind Field::TYPE_BYTES;
const Field_Kind Field::TYPE_UINT32;
const Field_Kind Field::TYPE_ENUM;
const Field_Kind Field::TYPE_SFIXED32;
const Field_Kind Field::TYPE_SFIXED64;
const Field_Kind Field::TYPE_SINT32;
const Field_Kind Field::TYPE_SINT64;
const Field_Kind Field::Kind_MIN;
const Field_Kind Field::Kind_MAX;
const int Field::Kind_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_enum_descriptors[1];
}
bool Field_Cardinality_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const Field_Cardinality Field::CARDINALITY_UNKNOWN;
const Field_Cardinality Field::CARDINALITY_OPTIONAL;
const Field_Cardinality Field::CARDINALITY_REQUIRED;
const Field_Cardinality Field::CARDINALITY_REPEATED;
const Field_Cardinality Field::Cardinality_MIN;
const Field_Cardinality Field::Cardinality_MAX;
const int Field::Cardinality_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* Syntax_descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_enum_descriptors[2];
}
bool Syntax_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
      return true;
    default:
      return false;
  }
}


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

void Type::_slow_mutable_source_context() {
  source_context_ = ::google::protobuf::Arena::Create< ::google::protobuf::SourceContext >(
      GetArenaNoVirtual());
}
::google::protobuf::SourceContext* Type::_slow_release_source_context() {
  if (source_context_ == NULL) {
    return NULL;
  } else {
    ::google::protobuf::SourceContext* temp = new ::google::protobuf::SourceContext(*source_context_);
    source_context_ = NULL;
    return temp;
  }
}
::google::protobuf::SourceContext* Type::unsafe_arena_release_source_context() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Type.source_context)
  
  ::google::protobuf::SourceContext* temp = source_context_;
  source_context_ = NULL;
  return temp;
}
void Type::unsafe_arena_set_allocated_source_context(
    ::google::protobuf::SourceContext* source_context) {
  if (GetArenaNoVirtual() == NULL) {
    delete source_context_;
  }
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.source_context)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Type::kNameFieldNumber;
const int Type::kFieldsFieldNumber;
const int Type::kOneofsFieldNumber;
const int Type::kOptionsFieldNumber;
const int Type::kSourceContextFieldNumber;
const int Type::kSyntaxFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Type::Type()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.Type)
}
Type::Type(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  fields_(arena),
  oneofs_(arena),
  options_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Type)
}
Type::Type(const Type& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      fields_(from.fields_),
      oneofs_(from.oneofs_),
      options_(from.options_),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.name().size() > 0) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_source_context()) {
    source_context_ = new ::google::protobuf::SourceContext(*from.source_context_);
  } else {
    source_context_ = NULL;
  }
  syntax_ = from.syntax_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Type)
}

void Type::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&source_context_, 0, reinterpret_cast<char*>(&syntax_) -
    reinterpret_cast<char*>(&source_context_) + sizeof(syntax_));
  _cached_size_ = 0;
}

Type::~Type() {
  // @@protoc_insertion_point(destructor:google.protobuf.Type)
  SharedDtor();
}

void Type::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

  name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
  if (this != internal_default_instance()) {
    delete source_context_;
  }
}

void Type::ArenaDtor(void* object) {
  Type* _this = reinterpret_cast< Type* >(object);
  (void)_this;
}
void Type::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Type::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Type::descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Type& Type::default_instance() {
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  return *internal_default_instance();
}

Type* Type::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<Type>(arena);
}

void Type::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Type)
  fields_.Clear();
  oneofs_.Clear();
  options_.Clear();
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  if (GetArenaNoVirtual() == NULL && source_context_ != NULL) {
    delete source_context_;
  }
  source_context_ = NULL;
  syntax_ = 0;
}

bool Type::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.Type)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Type.name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.Field fields = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_fields()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated string oneofs = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_oneofs()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->oneofs(this->oneofs_size() - 1).data(),
            this->oneofs(this->oneofs_size() - 1).length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Type.oneofs"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.Option options = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.SourceContext source_context = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_source_context()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.Syntax syntax = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(48u)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_syntax(static_cast< ::google::protobuf::Syntax >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.Type)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.Type)
  return false;
#undef DO_
}

void Type::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.Type)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Type.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // repeated .google.protobuf.Field fields = 2;
  for (unsigned int i = 0, n = this->fields_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->fields(i), output);
  }

  // repeated string oneofs = 3;
  for (int i = 0, n = this->oneofs_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->oneofs(i).data(), this->oneofs(i).length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Type.oneofs");
    ::google::protobuf::internal::WireFormatLite::WriteString(
      3, this->oneofs(i), output);
  }

  // repeated .google.protobuf.Option options = 4;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, this->options(i), output);
  }

  // .google.protobuf.SourceContext source_context = 5;
  if (this->has_source_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, *this->source_context_, output);
  }

  // .google.protobuf.Syntax syntax = 6;
  if (this->syntax() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      6, this->syntax(), output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.Type)
}

::google::protobuf::uint8* Type::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Type.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.Field fields = 2;
  for (unsigned int i = 0, n = this->fields_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        2, this->fields(i), deterministic, target);
  }

  // repeated string oneofs = 3;
  for (int i = 0, n = this->oneofs_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->oneofs(i).data(), this->oneofs(i).length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Type.oneofs");
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(3, this->oneofs(i), target);
  }

  // repeated .google.protobuf.Option options = 4;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        4, this->options(i), deterministic, target);
  }

  // .google.protobuf.SourceContext source_context = 5;
  if (this->has_source_context()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        5, *this->source_context_, deterministic, target);
  }

  // .google.protobuf.Syntax syntax = 6;
  if (this->syntax() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      6, this->syntax(), target);
  }

  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type)
  return target;
}

size_t Type::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Type)
  size_t total_size = 0;

  // repeated .google.protobuf.Field fields = 2;
  {
    unsigned int count = this->fields_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->fields(i));
    }
  }

  // repeated string oneofs = 3;
  total_size += 1 *
      ::google::protobuf::internal::FromIntSize(this->oneofs_size());
  for (int i = 0, n = this->oneofs_size(); i < n; i++) {
    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
      this->oneofs(i));
  }

  // repeated .google.protobuf.Option options = 4;
  {
    unsigned int count = this->options_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options(i));
    }
  }

  // string name = 1;
  if (this->name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name());
  }

  // .google.protobuf.SourceContext source_context = 5;
  if (this->has_source_context()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        *this->source_context_);
  }

  // .google.protobuf.Syntax syntax = 6;
  if (this->syntax() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void Type::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Type)
  GOOGLE_DCHECK_NE(&from, this);
  const Type* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const Type>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Type)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Type)
    MergeFrom(*source);
  }
}

void Type::MergeFrom(const Type& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  fields_.MergeFrom(from.fields_);
  oneofs_.MergeFrom(from.oneofs_);
  options_.MergeFrom(from.options_);
  if (from.name().size() > 0) {
    set_name(from.name());
  }
  if (from.has_source_context()) {
    mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
  }
  if (from.syntax() != 0) {
    set_syntax(from.syntax());
  }
}

void Type::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Type)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void Type::CopyFrom(const Type& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Type)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Type::IsInitialized() const {
  return true;
}

void Type::Swap(Type* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    Type* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void Type::UnsafeArenaSwap(Type* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void Type::InternalSwap(Type* other) {
  fields_.InternalSwap(&other->fields_);
  oneofs_.InternalSwap(&other->oneofs_);
  options_.InternalSwap(&other->options_);
  name_.Swap(&other->name_);
  std::swap(source_context_, other->source_context_);
  std::swap(syntax_, other->syntax_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata Type::GetMetadata() const {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// Type

// string name = 1;
void Type::clear_name() {
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Type::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.name)
  return name_.Get();
}
void Type::set_name(const ::std::string& value) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Type.name)
}
void Type::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name)
}
void Type::set_name(const char* value,
    size_t size) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.name)
}
::std::string* Type::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name)
  return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Type::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
  
  return name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Type::unsafe_arena_release_name() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Type.name)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Type::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name)
}
void Type::unsafe_arena_set_allocated_name(
    ::std::string* name) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (name != NULL) {
    
  } else {
    
  }
  name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      name, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.name)
}

// repeated .google.protobuf.Field fields = 2;
int Type::fields_size() const {
  return fields_.size();
}
void Type::clear_fields() {
  fields_.Clear();
}
const ::google::protobuf::Field& Type::fields(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.fields)
  return fields_.Get(index);
}
::google::protobuf::Field* Type::mutable_fields(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields)
  return fields_.Mutable(index);
}
::google::protobuf::Field* Type::add_fields() {
  // @@protoc_insertion_point(field_add:google.protobuf.Type.fields)
  return fields_.Add();
}
::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
Type::mutable_fields() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields)
  return &fields_;
}
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
Type::fields() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
  return fields_;
}

// repeated string oneofs = 3;
int Type::oneofs_size() const {
  return oneofs_.size();
}
void Type::clear_oneofs() {
  oneofs_.Clear();
}
const ::std::string& Type::oneofs(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.oneofs)
  return oneofs_.Get(index);
}
::std::string* Type::mutable_oneofs(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.oneofs)
  return oneofs_.Mutable(index);
}
void Type::set_oneofs(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
  oneofs_.Mutable(index)->assign(value);
}
#if LANG_CXX11
void Type::set_oneofs(int index, ::std::string&& value) {
  // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
  oneofs_.Mutable(index)->assign(std::move(value));
}
#endif
void Type::set_oneofs(int index, const char* value) {
  GOOGLE_DCHECK(value != NULL);
  oneofs_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs)
}
void Type::set_oneofs(int index, const char* value, size_t size) {
  oneofs_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs)
}
::std::string* Type::add_oneofs() {
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs)
  return oneofs_.Add();
}
void Type::add_oneofs(const ::std::string& value) {
  oneofs_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
}
#if LANG_CXX11
void Type::add_oneofs(::std::string&& value) {
  oneofs_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
}
#endif
void Type::add_oneofs(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  oneofs_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs)
}
void Type::add_oneofs(const char* value, size_t size) {
  oneofs_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.Type.oneofs)
}
const ::google::protobuf::RepeatedPtrField< ::std::string>&
Type::oneofs() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs)
  return oneofs_;
}
::google::protobuf::RepeatedPtrField< ::std::string>*
Type::mutable_oneofs() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs)
  return &oneofs_;
}

// repeated .google.protobuf.Option options = 4;
int Type::options_size() const {
  return options_.size();
}
void Type::clear_options() {
  options_.Clear();
}
const ::google::protobuf::Option& Type::options(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.options)
  return options_.Get(index);
}
::google::protobuf::Option* Type::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options)
  return options_.Mutable(index);
}
::google::protobuf::Option* Type::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.Type.options)
  return options_.Add();
}
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Type::mutable_options() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options)
  return &options_;
}
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Type::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
  return options_;
}

// .google.protobuf.SourceContext source_context = 5;
bool Type::has_source_context() const {
  return this != internal_default_instance() && source_context_ != NULL;
}
void Type::clear_source_context() {
  if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
  source_context_ = NULL;
}
const ::google::protobuf::SourceContext& Type::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
  return source_context_ != NULL ? *source_context_
                         : *::google::protobuf::SourceContext::internal_default_instance();
}
::google::protobuf::SourceContext* Type::mutable_source_context() {
  
  if (source_context_ == NULL) {
    _slow_mutable_source_context();
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context)
  return source_context_;
}
::google::protobuf::SourceContext* Type::release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context)
  
  if (GetArenaNoVirtual() != NULL) {
    return _slow_release_source_context();
  } else {
    ::google::protobuf::SourceContext* temp = source_context_;
    source_context_ = NULL;
    return temp;
  }
}
 void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete source_context_;
  }
  if (source_context != NULL) {
    if (message_arena != NULL) {
      message_arena->Own(source_context);
    }
  }
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
}

// .google.protobuf.Syntax syntax = 6;
void Type::clear_syntax() {
  syntax_ = 0;
}
::google::protobuf::Syntax Type::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
  return static_cast< ::google::protobuf::Syntax >(syntax_);
}
void Type::set_syntax(::google::protobuf::Syntax value) {
  
  syntax_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Field::kKindFieldNumber;
const int Field::kCardinalityFieldNumber;
const int Field::kNumberFieldNumber;
const int Field::kNameFieldNumber;
const int Field::kTypeUrlFieldNumber;
const int Field::kOneofIndexFieldNumber;
const int Field::kPackedFieldNumber;
const int Field::kOptionsFieldNumber;
const int Field::kJsonNameFieldNumber;
const int Field::kDefaultValueFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Field::Field()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.Field)
}
Field::Field(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  options_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Field)
}
Field::Field(const Field& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      options_(from.options_),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.name().size() > 0) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.type_url().size() > 0) {
    type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url(),
      GetArenaNoVirtual());
  }
  json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.json_name().size() > 0) {
    json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name(),
      GetArenaNoVirtual());
  }
  default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.default_value().size() > 0) {
    default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value(),
      GetArenaNoVirtual());
  }
  ::memcpy(&kind_, &from.kind_,
    reinterpret_cast<char*>(&packed_) -
    reinterpret_cast<char*>(&kind_) + sizeof(packed_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Field)
}

void Field::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&kind_, 0, reinterpret_cast<char*>(&packed_) -
    reinterpret_cast<char*>(&kind_) + sizeof(packed_));
  _cached_size_ = 0;
}

Field::~Field() {
  // @@protoc_insertion_point(destructor:google.protobuf.Field)
  SharedDtor();
}

void Field::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

  name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
  type_url_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
  json_name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
  default_value_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
}

void Field::ArenaDtor(void* object) {
  Field* _this = reinterpret_cast< Field* >(object);
  (void)_this;
}
void Field::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Field::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Field::descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Field& Field::default_instance() {
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  return *internal_default_instance();
}

Field* Field::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<Field>(arena);
}

void Field::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Field)
  options_.Clear();
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  type_url_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  json_name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  default_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  ::memset(&kind_, 0, reinterpret_cast<char*>(&packed_) -
    reinterpret_cast<char*>(&kind_) + sizeof(packed_));
}

bool Field::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.Field)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .google.protobuf.Field.Kind kind = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_kind(static_cast< ::google::protobuf::Field_Kind >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.Field.Cardinality cardinality = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_cardinality(static_cast< ::google::protobuf::Field_Cardinality >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // int32 number = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &number_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string name = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Field.name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string type_url = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_type_url()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->type_url().data(), this->type_url().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Field.type_url"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // int32 oneof_index = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(56u)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &oneof_index_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // bool packed = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(64u)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &packed_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.Option options = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(74u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string json_name = 10;
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(82u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_json_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->json_name().data(), this->json_name().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Field.json_name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string default_value = 11;
      case 11: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(90u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_default_value()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->default_value().data(), this->default_value().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Field.default_value"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.Field)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.Field)
  return false;
#undef DO_
}

void Field::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.Field)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .google.protobuf.Field.Kind kind = 1;
  if (this->kind() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->kind(), output);
  }

  // .google.protobuf.Field.Cardinality cardinality = 2;
  if (this->cardinality() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->cardinality(), output);
  }

  // int32 number = 3;
  if (this->number() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
  }

  // string name = 4;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      4, this->name(), output);
  }

  // string type_url = 6;
  if (this->type_url().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->type_url().data(), this->type_url().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.type_url");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      6, this->type_url(), output);
  }

  // int32 oneof_index = 7;
  if (this->oneof_index() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->oneof_index(), output);
  }

  // bool packed = 8;
  if (this->packed() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(8, this->packed(), output);
  }

  // repeated .google.protobuf.Option options = 9;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      9, this->options(i), output);
  }

  // string json_name = 10;
  if (this->json_name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->json_name().data(), this->json_name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.json_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      10, this->json_name(), output);
  }

  // string default_value = 11;
  if (this->default_value().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->default_value().data(), this->default_value().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.default_value");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      11, this->default_value(), output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.Field)
}

::google::protobuf::uint8* Field::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .google.protobuf.Field.Kind kind = 1;
  if (this->kind() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->kind(), target);
  }

  // .google.protobuf.Field.Cardinality cardinality = 2;
  if (this->cardinality() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->cardinality(), target);
  }

  // int32 number = 3;
  if (this->number() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
  }

  // string name = 4;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->name(), target);
  }

  // string type_url = 6;
  if (this->type_url().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->type_url().data(), this->type_url().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.type_url");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        6, this->type_url(), target);
  }

  // int32 oneof_index = 7;
  if (this->oneof_index() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->oneof_index(), target);
  }

  // bool packed = 8;
  if (this->packed() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(8, this->packed(), target);
  }

  // repeated .google.protobuf.Option options = 9;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        9, this->options(i), deterministic, target);
  }

  // string json_name = 10;
  if (this->json_name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->json_name().data(), this->json_name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.json_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        10, this->json_name(), target);
  }

  // string default_value = 11;
  if (this->default_value().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->default_value().data(), this->default_value().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Field.default_value");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        11, this->default_value(), target);
  }

  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
  return target;
}

size_t Field::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Field)
  size_t total_size = 0;

  // repeated .google.protobuf.Option options = 9;
  {
    unsigned int count = this->options_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options(i));
    }
  }

  // string name = 4;
  if (this->name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name());
  }

  // string type_url = 6;
  if (this->type_url().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->type_url());
  }

  // string json_name = 10;
  if (this->json_name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->json_name());
  }

  // string default_value = 11;
  if (this->default_value().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->default_value());
  }

  // .google.protobuf.Field.Kind kind = 1;
  if (this->kind() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->kind());
  }

  // .google.protobuf.Field.Cardinality cardinality = 2;
  if (this->cardinality() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->cardinality());
  }

  // int32 number = 3;
  if (this->number() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::Int32Size(
        this->number());
  }

  // int32 oneof_index = 7;
  if (this->oneof_index() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::Int32Size(
        this->oneof_index());
  }

  // bool packed = 8;
  if (this->packed() != 0) {
    total_size += 1 + 1;
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void Field::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Field)
  GOOGLE_DCHECK_NE(&from, this);
  const Field* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const Field>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Field)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Field)
    MergeFrom(*source);
  }
}

void Field::MergeFrom(const Field& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  options_.MergeFrom(from.options_);
  if (from.name().size() > 0) {
    set_name(from.name());
  }
  if (from.type_url().size() > 0) {
    set_type_url(from.type_url());
  }
  if (from.json_name().size() > 0) {
    set_json_name(from.json_name());
  }
  if (from.default_value().size() > 0) {
    set_default_value(from.default_value());
  }
  if (from.kind() != 0) {
    set_kind(from.kind());
  }
  if (from.cardinality() != 0) {
    set_cardinality(from.cardinality());
  }
  if (from.number() != 0) {
    set_number(from.number());
  }
  if (from.oneof_index() != 0) {
    set_oneof_index(from.oneof_index());
  }
  if (from.packed() != 0) {
    set_packed(from.packed());
  }
}

void Field::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Field)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void Field::CopyFrom(const Field& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Field)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Field::IsInitialized() const {
  return true;
}

void Field::Swap(Field* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    Field* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void Field::UnsafeArenaSwap(Field* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void Field::InternalSwap(Field* other) {
  options_.InternalSwap(&other->options_);
  name_.Swap(&other->name_);
  type_url_.Swap(&other->type_url_);
  json_name_.Swap(&other->json_name_);
  default_value_.Swap(&other->default_value_);
  std::swap(kind_, other->kind_);
  std::swap(cardinality_, other->cardinality_);
  std::swap(number_, other->number_);
  std::swap(oneof_index_, other->oneof_index_);
  std::swap(packed_, other->packed_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata Field::GetMetadata() const {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// Field

// .google.protobuf.Field.Kind kind = 1;
void Field::clear_kind() {
  kind_ = 0;
}
::google::protobuf::Field_Kind Field::kind() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.kind)
  return static_cast< ::google::protobuf::Field_Kind >(kind_);
}
void Field::set_kind(::google::protobuf::Field_Kind value) {
  
  kind_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Field.kind)
}

// .google.protobuf.Field.Cardinality cardinality = 2;
void Field::clear_cardinality() {
  cardinality_ = 0;
}
::google::protobuf::Field_Cardinality Field::cardinality() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.cardinality)
  return static_cast< ::google::protobuf::Field_Cardinality >(cardinality_);
}
void Field::set_cardinality(::google::protobuf::Field_Cardinality value) {
  
  cardinality_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Field.cardinality)
}

// int32 number = 3;
void Field::clear_number() {
  number_ = 0;
}
::google::protobuf::int32 Field::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.number)
  return number_;
}
void Field::set_number(::google::protobuf::int32 value) {
  
  number_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Field.number)
}

// string name = 4;
void Field::clear_name() {
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Field::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.name)
  return name_.Get();
}
void Field::set_name(const ::std::string& value) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.name)
}
void Field::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name)
}
void Field::set_name(const char* value,
    size_t size) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.name)
}
::std::string* Field::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name)
  return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
  
  return name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::unsafe_arena_release_name() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.name)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Field::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name)
}
void Field::unsafe_arena_set_allocated_name(
    ::std::string* name) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (name != NULL) {
    
  } else {
    
  }
  name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      name, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.name)
}

// string type_url = 6;
void Field::clear_type_url() {
  type_url_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Field::type_url() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url)
  return type_url_.Get();
}
void Field::set_type_url(const ::std::string& value) {
  
  type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
}
void Field::set_type_url(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.type_url)
}
void Field::set_type_url(const char* value,
    size_t size) {
  
  type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.type_url)
}
::std::string* Field::mutable_type_url() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url)
  return type_url_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::release_type_url() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
  
  return type_url_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::unsafe_arena_release_type_url() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.type_url)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return type_url_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Field::set_allocated_type_url(::std::string* type_url) {
  if (type_url != NULL) {
    
  } else {
    
  }
  type_url_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url)
}
void Field::unsafe_arena_set_allocated_type_url(
    ::std::string* type_url) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (type_url != NULL) {
    
  } else {
    
  }
  type_url_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      type_url, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.type_url)
}

// int32 oneof_index = 7;
void Field::clear_oneof_index() {
  oneof_index_ = 0;
}
::google::protobuf::int32 Field::oneof_index() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.oneof_index)
  return oneof_index_;
}
void Field::set_oneof_index(::google::protobuf::int32 value) {
  
  oneof_index_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index)
}

// bool packed = 8;
void Field::clear_packed() {
  packed_ = false;
}
bool Field::packed() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.packed)
  return packed_;
}
void Field::set_packed(bool value) {
  
  packed_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Field.packed)
}

// repeated .google.protobuf.Option options = 9;
int Field::options_size() const {
  return options_.size();
}
void Field::clear_options() {
  options_.Clear();
}
const ::google::protobuf::Option& Field::options(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.options)
  return options_.Get(index);
}
::google::protobuf::Option* Field::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options)
  return options_.Mutable(index);
}
::google::protobuf::Option* Field::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.Field.options)
  return options_.Add();
}
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Field::mutable_options() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options)
  return &options_;
}
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Field::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Field.options)
  return options_;
}

// string json_name = 10;
void Field::clear_json_name() {
  json_name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Field::json_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
  return json_name_.Get();
}
void Field::set_json_name(const ::std::string& value) {
  
  json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
}
void Field::set_json_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
}
void Field::set_json_name(const char* value,
    size_t size) {
  
  json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
}
::std::string* Field::mutable_json_name() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
  return json_name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::release_json_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
  
  return json_name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::unsafe_arena_release_json_name() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.json_name)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return json_name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Field::set_allocated_json_name(::std::string* json_name) {
  if (json_name != NULL) {
    
  } else {
    
  }
  json_name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}
void Field::unsafe_arena_set_allocated_json_name(
    ::std::string* json_name) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (json_name != NULL) {
    
  } else {
    
  }
  json_name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      json_name, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.json_name)
}

// string default_value = 11;
void Field::clear_default_value() {
  default_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Field::default_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value)
  return default_value_.Get();
}
void Field::set_default_value(const ::std::string& value) {
  
  default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
}
void Field::set_default_value(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.default_value)
}
void Field::set_default_value(const char* value,
    size_t size) {
  
  default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.default_value)
}
::std::string* Field::mutable_default_value() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value)
  return default_value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::release_default_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
  
  return default_value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Field::unsafe_arena_release_default_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.default_value)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return default_value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Field::set_allocated_default_value(::std::string* default_value) {
  if (default_value != NULL) {
    
  } else {
    
  }
  default_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value)
}
void Field::unsafe_arena_set_allocated_default_value(
    ::std::string* default_value) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (default_value != NULL) {
    
  } else {
    
  }
  default_value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      default_value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.default_value)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

void Enum::_slow_mutable_source_context() {
  source_context_ = ::google::protobuf::Arena::Create< ::google::protobuf::SourceContext >(
      GetArenaNoVirtual());
}
::google::protobuf::SourceContext* Enum::_slow_release_source_context() {
  if (source_context_ == NULL) {
    return NULL;
  } else {
    ::google::protobuf::SourceContext* temp = new ::google::protobuf::SourceContext(*source_context_);
    source_context_ = NULL;
    return temp;
  }
}
::google::protobuf::SourceContext* Enum::unsafe_arena_release_source_context() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Enum.source_context)
  
  ::google::protobuf::SourceContext* temp = source_context_;
  source_context_ = NULL;
  return temp;
}
void Enum::unsafe_arena_set_allocated_source_context(
    ::google::protobuf::SourceContext* source_context) {
  if (GetArenaNoVirtual() == NULL) {
    delete source_context_;
  }
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.source_context)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Enum::kNameFieldNumber;
const int Enum::kEnumvalueFieldNumber;
const int Enum::kOptionsFieldNumber;
const int Enum::kSourceContextFieldNumber;
const int Enum::kSyntaxFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Enum::Enum()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.Enum)
}
Enum::Enum(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  enumvalue_(arena),
  options_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Enum)
}
Enum::Enum(const Enum& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      enumvalue_(from.enumvalue_),
      options_(from.options_),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.name().size() > 0) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_source_context()) {
    source_context_ = new ::google::protobuf::SourceContext(*from.source_context_);
  } else {
    source_context_ = NULL;
  }
  syntax_ = from.syntax_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum)
}

void Enum::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&source_context_, 0, reinterpret_cast<char*>(&syntax_) -
    reinterpret_cast<char*>(&source_context_) + sizeof(syntax_));
  _cached_size_ = 0;
}

Enum::~Enum() {
  // @@protoc_insertion_point(destructor:google.protobuf.Enum)
  SharedDtor();
}

void Enum::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

  name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
  if (this != internal_default_instance()) {
    delete source_context_;
  }
}

void Enum::ArenaDtor(void* object) {
  Enum* _this = reinterpret_cast< Enum* >(object);
  (void)_this;
}
void Enum::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Enum::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Enum::descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Enum& Enum::default_instance() {
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  return *internal_default_instance();
}

Enum* Enum::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<Enum>(arena);
}

void Enum::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Enum)
  enumvalue_.Clear();
  options_.Clear();
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  if (GetArenaNoVirtual() == NULL && source_context_ != NULL) {
    delete source_context_;
  }
  source_context_ = NULL;
  syntax_ = 0;
}

bool Enum::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.Enum)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Enum.name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.EnumValue enumvalue = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_enumvalue()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.Option options = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.SourceContext source_context = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_source_context()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.Syntax syntax = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_syntax(static_cast< ::google::protobuf::Syntax >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.Enum)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.Enum)
  return false;
#undef DO_
}

void Enum::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.Enum)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Enum.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // repeated .google.protobuf.EnumValue enumvalue = 2;
  for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->enumvalue(i), output);
  }

  // repeated .google.protobuf.Option options = 3;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->options(i), output);
  }

  // .google.protobuf.SourceContext source_context = 4;
  if (this->has_source_context()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, *this->source_context_, output);
  }

  // .google.protobuf.Syntax syntax = 5;
  if (this->syntax() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      5, this->syntax(), output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.Enum)
}

::google::protobuf::uint8* Enum::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Enum.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.EnumValue enumvalue = 2;
  for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        2, this->enumvalue(i), deterministic, target);
  }

  // repeated .google.protobuf.Option options = 3;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        3, this->options(i), deterministic, target);
  }

  // .google.protobuf.SourceContext source_context = 4;
  if (this->has_source_context()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        4, *this->source_context_, deterministic, target);
  }

  // .google.protobuf.Syntax syntax = 5;
  if (this->syntax() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      5, this->syntax(), target);
  }

  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum)
  return target;
}

size_t Enum::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Enum)
  size_t total_size = 0;

  // repeated .google.protobuf.EnumValue enumvalue = 2;
  {
    unsigned int count = this->enumvalue_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->enumvalue(i));
    }
  }

  // repeated .google.protobuf.Option options = 3;
  {
    unsigned int count = this->options_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options(i));
    }
  }

  // string name = 1;
  if (this->name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name());
  }

  // .google.protobuf.SourceContext source_context = 4;
  if (this->has_source_context()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        *this->source_context_);
  }

  // .google.protobuf.Syntax syntax = 5;
  if (this->syntax() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void Enum::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Enum)
  GOOGLE_DCHECK_NE(&from, this);
  const Enum* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const Enum>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Enum)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Enum)
    MergeFrom(*source);
  }
}

void Enum::MergeFrom(const Enum& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  enumvalue_.MergeFrom(from.enumvalue_);
  options_.MergeFrom(from.options_);
  if (from.name().size() > 0) {
    set_name(from.name());
  }
  if (from.has_source_context()) {
    mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
  }
  if (from.syntax() != 0) {
    set_syntax(from.syntax());
  }
}

void Enum::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Enum)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void Enum::CopyFrom(const Enum& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Enum)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Enum::IsInitialized() const {
  return true;
}

void Enum::Swap(Enum* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    Enum* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void Enum::UnsafeArenaSwap(Enum* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void Enum::InternalSwap(Enum* other) {
  enumvalue_.InternalSwap(&other->enumvalue_);
  options_.InternalSwap(&other->options_);
  name_.Swap(&other->name_);
  std::swap(source_context_, other->source_context_);
  std::swap(syntax_, other->syntax_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata Enum::GetMetadata() const {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// Enum

// string name = 1;
void Enum::clear_name() {
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Enum::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.name)
  return name_.Get();
}
void Enum::set_name(const ::std::string& value) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Enum.name)
}
void Enum::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name)
}
void Enum::set_name(const char* value,
    size_t size) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Enum.name)
}
::std::string* Enum::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name)
  return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Enum::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
  
  return name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Enum::unsafe_arena_release_name() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Enum.name)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Enum::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name)
}
void Enum::unsafe_arena_set_allocated_name(
    ::std::string* name) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (name != NULL) {
    
  } else {
    
  }
  name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      name, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.name)
}

// repeated .google.protobuf.EnumValue enumvalue = 2;
int Enum::enumvalue_size() const {
  return enumvalue_.size();
}
void Enum::clear_enumvalue() {
  enumvalue_.Clear();
}
const ::google::protobuf::EnumValue& Enum::enumvalue(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue)
  return enumvalue_.Get(index);
}
::google::protobuf::EnumValue* Enum::mutable_enumvalue(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue)
  return enumvalue_.Mutable(index);
}
::google::protobuf::EnumValue* Enum::add_enumvalue() {
  // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue)
  return enumvalue_.Add();
}
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
Enum::mutable_enumvalue() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue)
  return &enumvalue_;
}
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
Enum::enumvalue() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
  return enumvalue_;
}

// repeated .google.protobuf.Option options = 3;
int Enum::options_size() const {
  return options_.size();
}
void Enum::clear_options() {
  options_.Clear();
}
const ::google::protobuf::Option& Enum::options(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.options)
  return options_.Get(index);
}
::google::protobuf::Option* Enum::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options)
  return options_.Mutable(index);
}
::google::protobuf::Option* Enum::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.Enum.options)
  return options_.Add();
}
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Enum::mutable_options() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options)
  return &options_;
}
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Enum::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
  return options_;
}

// .google.protobuf.SourceContext source_context = 4;
bool Enum::has_source_context() const {
  return this != internal_default_instance() && source_context_ != NULL;
}
void Enum::clear_source_context() {
  if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
  source_context_ = NULL;
}
const ::google::protobuf::SourceContext& Enum::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
  return source_context_ != NULL ? *source_context_
                         : *::google::protobuf::SourceContext::internal_default_instance();
}
::google::protobuf::SourceContext* Enum::mutable_source_context() {
  
  if (source_context_ == NULL) {
    _slow_mutable_source_context();
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context)
  return source_context_;
}
::google::protobuf::SourceContext* Enum::release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context)
  
  if (GetArenaNoVirtual() != NULL) {
    return _slow_release_source_context();
  } else {
    ::google::protobuf::SourceContext* temp = source_context_;
    source_context_ = NULL;
    return temp;
  }
}
 void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete source_context_;
  }
  if (source_context != NULL) {
    if (message_arena != NULL) {
      message_arena->Own(source_context);
    }
  }
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
}

// .google.protobuf.Syntax syntax = 5;
void Enum::clear_syntax() {
  syntax_ = 0;
}
::google::protobuf::Syntax Enum::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
  return static_cast< ::google::protobuf::Syntax >(syntax_);
}
void Enum::set_syntax(::google::protobuf::Syntax value) {
  
  syntax_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumValue::kNameFieldNumber;
const int EnumValue::kNumberFieldNumber;
const int EnumValue::kOptionsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EnumValue::EnumValue()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.EnumValue)
}
EnumValue::EnumValue(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  options_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValue)
}
EnumValue::EnumValue(const EnumValue& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      options_(from.options_),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.name().size() > 0) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  number_ = from.number_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue)
}

void EnumValue::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  number_ = 0;
  _cached_size_ = 0;
}

EnumValue::~EnumValue() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumValue)
  SharedDtor();
}

void EnumValue::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

  name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
}

void EnumValue::ArenaDtor(void* object) {
  EnumValue* _this = reinterpret_cast< EnumValue* >(object);
  (void)_this;
}
void EnumValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void EnumValue::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* EnumValue::descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const EnumValue& EnumValue::default_instance() {
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  return *internal_default_instance();
}

EnumValue* EnumValue::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<EnumValue>(arena);
}

void EnumValue::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue)
  options_.Clear();
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  number_ = 0;
}

bool EnumValue::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.EnumValue)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.EnumValue.name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // int32 number = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &number_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.Option options = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValue)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValue)
  return false;
#undef DO_
}

void EnumValue::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValue)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.EnumValue.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // int32 number = 2;
  if (this->number() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
  }

  // repeated .google.protobuf.Option options = 3;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->options(i), output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValue)
}

::google::protobuf::uint8* EnumValue::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.EnumValue.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // int32 number = 2;
  if (this->number() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
  }

  // repeated .google.protobuf.Option options = 3;
  for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        3, this->options(i), deterministic, target);
  }

  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue)
  return target;
}

size_t EnumValue::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValue)
  size_t total_size = 0;

  // repeated .google.protobuf.Option options = 3;
  {
    unsigned int count = this->options_size();
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options(i));
    }
  }

  // string name = 1;
  if (this->name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name());
  }

  // int32 number = 2;
  if (this->number() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::Int32Size(
        this->number());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void EnumValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValue)
  GOOGLE_DCHECK_NE(&from, this);
  const EnumValue* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const EnumValue>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValue)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.EnumValue)
    MergeFrom(*source);
  }
}

void EnumValue::MergeFrom(const EnumValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  options_.MergeFrom(from.options_);
  if (from.name().size() > 0) {
    set_name(from.name());
  }
  if (from.number() != 0) {
    set_number(from.number());
  }
}

void EnumValue::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.EnumValue)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EnumValue::CopyFrom(const EnumValue& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValue)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumValue::IsInitialized() const {
  return true;
}

void EnumValue::Swap(EnumValue* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    EnumValue* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void EnumValue::UnsafeArenaSwap(EnumValue* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void EnumValue::InternalSwap(EnumValue* other) {
  options_.InternalSwap(&other->options_);
  name_.Swap(&other->name_);
  std::swap(number_, other->number_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata EnumValue::GetMetadata() const {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// EnumValue

// string name = 1;
void EnumValue::clear_name() {
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& EnumValue::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name)
  return name_.Get();
}
void EnumValue::set_name(const ::std::string& value) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name)
}
void EnumValue::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name)
}
void EnumValue::set_name(const char* value,
    size_t size) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValue.name)
}
::std::string* EnumValue::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name)
  return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* EnumValue::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
  
  return name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* EnumValue::unsafe_arena_release_name() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumValue.name)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void EnumValue::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name)
}
void EnumValue::unsafe_arena_set_allocated_name(
    ::std::string* name) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (name != NULL) {
    
  } else {
    
  }
  name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      name, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValue.name)
}

// int32 number = 2;
void EnumValue::clear_number() {
  number_ = 0;
}
::google::protobuf::int32 EnumValue::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.number)
  return number_;
}
void EnumValue::set_number(::google::protobuf::int32 value) {
  
  number_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.number)
}

// repeated .google.protobuf.Option options = 3;
int EnumValue::options_size() const {
  return options_.size();
}
void EnumValue::clear_options() {
  options_.Clear();
}
const ::google::protobuf::Option& EnumValue::options(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options)
  return options_.Get(index);
}
::google::protobuf::Option* EnumValue::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options)
  return options_.Mutable(index);
}
::google::protobuf::Option* EnumValue::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options)
  return options_.Add();
}
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
EnumValue::mutable_options() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options)
  return &options_;
}
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
EnumValue::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
  return options_;
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

void Option::_slow_mutable_value() {
  value_ = ::google::protobuf::Arena::Create< ::google::protobuf::Any >(
      GetArenaNoVirtual());
}
::google::protobuf::Any* Option::_slow_release_value() {
  if (value_ == NULL) {
    return NULL;
  } else {
    ::google::protobuf::Any* temp = new ::google::protobuf::Any(*value_);
    value_ = NULL;
    return temp;
  }
}
::google::protobuf::Any* Option::unsafe_arena_release_value() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Option.value)
  
  ::google::protobuf::Any* temp = value_;
  value_ = NULL;
  return temp;
}
void Option::unsafe_arena_set_allocated_value(
    ::google::protobuf::Any* value) {
  if (GetArenaNoVirtual() == NULL) {
    delete value_;
  }
  value_ = value;
  if (value) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.value)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Option::kNameFieldNumber;
const int Option::kValueFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Option::Option()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
    protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  }
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.Option)
}
Option::Option(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
#endif  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Option)
}
Option::Option(const Option& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _cached_size_(0) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.name().size() > 0) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_value()) {
    value_ = new ::google::protobuf::Any(*from.value_);
  } else {
    value_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.Option)
}

void Option::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  value_ = NULL;
  _cached_size_ = 0;
}

Option::~Option() {
  // @@protoc_insertion_point(destructor:google.protobuf.Option)
  SharedDtor();
}

void Option::SharedDtor() {
  ::google::protobuf::Arena* arena = GetArenaNoVirtual();
  if (arena != NULL) {
    return;
  }

  name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
  if (this != internal_default_instance()) {
    delete value_;
  }
}

void Option::ArenaDtor(void* object) {
  Option* _this = reinterpret_cast< Option* >(object);
  (void)_this;
}
void Option::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void Option::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* Option::descriptor() {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
}

const Option& Option::default_instance() {
  protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults();
  return *internal_default_instance();
}

Option* Option::New(::google::protobuf::Arena* arena) const {
  return ::google::protobuf::Arena::CreateMessage<Option>(arena);
}

void Option::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Option)
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
  if (GetArenaNoVirtual() == NULL && value_ != NULL) {
    delete value_;
  }
  value_ = NULL;
}

bool Option::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:google.protobuf.Option)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "google.protobuf.Option.name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.Any value = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_value()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.Option)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.Option)
  return false;
#undef DO_
}

void Option::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:google.protobuf.Option)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Option.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // .google.protobuf.Any value = 2;
  if (this->has_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, *this->value_, output);
  }

  // @@protoc_insertion_point(serialize_end:google.protobuf.Option)
}

::google::protobuf::uint8* Option::InternalSerializeWithCachedSizesToArray(
    bool deterministic, ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // string name = 1;
  if (this->name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "google.protobuf.Option.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // .google.protobuf.Any value = 2;
  if (this->has_value()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageNoVirtualToArray(
        2, *this->value_, deterministic, target);
  }

  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option)
  return target;
}

size_t Option::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Option)
  size_t total_size = 0;

  // string name = 1;
  if (this->name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name());
  }

  // .google.protobuf.Any value = 2;
  if (this->has_value()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        *this->value_);
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = cached_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void Option::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Option)
  GOOGLE_DCHECK_NE(&from, this);
  const Option* source =
      ::google::protobuf::internal::DynamicCastToGenerated<const Option>(
          &from);
  if (source == NULL) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Option)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Option)
    MergeFrom(*source);
  }
}

void Option::MergeFrom(const Option& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.name().size() > 0) {
    set_name(from.name());
  }
  if (from.has_value()) {
    mutable_value()->::google::protobuf::Any::MergeFrom(from.value());
  }
}

void Option::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Option)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void Option::CopyFrom(const Option& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Option)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Option::IsInitialized() const {
  return true;
}

void Option::Swap(Option* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    Option* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void Option::UnsafeArenaSwap(Option* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void Option::InternalSwap(Option* other) {
  name_.Swap(&other->name_);
  std::swap(value_, other->value_);
  std::swap(_cached_size_, other->_cached_size_);
}

::google::protobuf::Metadata Option::GetMetadata() const {
  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// Option

// string name = 1;
void Option::clear_name() {
  name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& Option::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Option.name)
  return name_.Get();
}
void Option::set_name(const ::std::string& value) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set:google.protobuf.Option.name)
}
void Option::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
              GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name)
}
void Option::set_name(const char* value,
    size_t size) {
  
  name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
      reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Option.name)
}
::std::string* Option::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name)
  return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Option::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
  
  return name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* Option::unsafe_arena_release_name() {
  // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Option.name)
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  
  return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      GetArenaNoVirtual());
}
void Option::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
      GetArenaNoVirtual());
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name)
}
void Option::unsafe_arena_set_allocated_name(
    ::std::string* name) {
  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
  if (name != NULL) {
    
  } else {
    
  }
  name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      name, GetArenaNoVirtual());
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.name)
}

// .google.protobuf.Any value = 2;
bool Option::has_value() const {
  return this != internal_default_instance() && value_ != NULL;
}
void Option::clear_value() {
  if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_;
  value_ = NULL;
}
const ::google::protobuf::Any& Option::value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Option.value)
  return value_ != NULL ? *value_
                         : *::google::protobuf::Any::internal_default_instance();
}
::google::protobuf::Any* Option::mutable_value() {
  
  if (value_ == NULL) {
    _slow_mutable_value();
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value)
  return value_;
}
::google::protobuf::Any* Option::release_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Option.value)
  
  if (GetArenaNoVirtual() != NULL) {
    return _slow_release_value();
  } else {
    ::google::protobuf::Any* temp = value_;
    value_ = NULL;
    return temp;
  }
}
 void Option::set_allocated_value(::google::protobuf::Any* value) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete value_;
  }
  if (value != NULL) {
    if (message_arena != NULL) {
      message_arena->Own(value);
    }
  }
  value_ = value;
  if (value) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)
