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

#include <google/protobuf/descriptor.pb.h>

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.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>
// This is a temporary google only hack
#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
#include "third_party/protobuf/version.h"
#endif
// @@protoc_insertion_point(includes)

namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ExtensionRangeOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FieldDescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FieldOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FileOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MessageOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MethodDescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MethodOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_OneofDescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_OneofOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ServiceOptions;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_SourceCodeInfo;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_UninterpretedOption;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ServiceDescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<3> scc_info_EnumDescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_DescriptorProto;
extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto;
}  // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto
namespace google {
namespace protobuf {
class FileDescriptorSetDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorSet>
      _instance;
} _FileDescriptorSet_default_instance_;
class FileDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorProto>
      _instance;
} _FileDescriptorProto_default_instance_;
class DescriptorProto_ExtensionRangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ExtensionRange>
      _instance;
} _DescriptorProto_ExtensionRange_default_instance_;
class DescriptorProto_ReservedRangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ReservedRange>
      _instance;
} _DescriptorProto_ReservedRange_default_instance_;
class DescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto>
      _instance;
} _DescriptorProto_default_instance_;
class ExtensionRangeOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ExtensionRangeOptions>
      _instance;
} _ExtensionRangeOptions_default_instance_;
class FieldDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<FieldDescriptorProto>
      _instance;
} _FieldDescriptorProto_default_instance_;
class OneofDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<OneofDescriptorProto>
      _instance;
} _OneofDescriptorProto_default_instance_;
class EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto_EnumReservedRange>
      _instance;
} _EnumDescriptorProto_EnumReservedRange_default_instance_;
class EnumDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto>
      _instance;
} _EnumDescriptorProto_default_instance_;
class EnumValueDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EnumValueDescriptorProto>
      _instance;
} _EnumValueDescriptorProto_default_instance_;
class ServiceDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ServiceDescriptorProto>
      _instance;
} _ServiceDescriptorProto_default_instance_;
class MethodDescriptorProtoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<MethodDescriptorProto>
      _instance;
} _MethodDescriptorProto_default_instance_;
class FileOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<FileOptions>
      _instance;
} _FileOptions_default_instance_;
class MessageOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<MessageOptions>
      _instance;
} _MessageOptions_default_instance_;
class FieldOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<FieldOptions>
      _instance;
} _FieldOptions_default_instance_;
class OneofOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<OneofOptions>
      _instance;
} _OneofOptions_default_instance_;
class EnumOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EnumOptions>
      _instance;
} _EnumOptions_default_instance_;
class EnumValueOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EnumValueOptions>
      _instance;
} _EnumValueOptions_default_instance_;
class ServiceOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ServiceOptions>
      _instance;
} _ServiceOptions_default_instance_;
class MethodOptionsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<MethodOptions>
      _instance;
} _MethodOptions_default_instance_;
class UninterpretedOption_NamePartDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption_NamePart>
      _instance;
} _UninterpretedOption_NamePart_default_instance_;
class UninterpretedOptionDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption>
      _instance;
} _UninterpretedOption_default_instance_;
class SourceCodeInfo_LocationDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo_Location>
      _instance;
} _SourceCodeInfo_Location_default_instance_;
class SourceCodeInfoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo>
      _instance;
} _SourceCodeInfo_default_instance_;
class GeneratedCodeInfo_AnnotationDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo_Annotation>
      _instance;
} _GeneratedCodeInfo_Annotation_default_instance_;
class GeneratedCodeInfoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo>
      _instance;
} _GeneratedCodeInfo_default_instance_;
}  // namespace protobuf
}  // namespace google
namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
static void InitDefaultsFileDescriptorSet() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_FileDescriptorSet_default_instance_;
    new (ptr) ::google::protobuf::FileDescriptorSet();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::FileDescriptorSet::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FileDescriptorSet =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFileDescriptorSet}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base,}};

static void InitDefaultsFileDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_FileDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::FileDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::FileDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 6, InitDefaultsFileDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base,}};

static void InitDefaultsDescriptorProto_ExtensionRange() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_DescriptorProto_ExtensionRange_default_instance_;
    new (ptr) ::google::protobuf::DescriptorProto_ExtensionRange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::DescriptorProto_ExtensionRange::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsDescriptorProto_ExtensionRange}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base,}};

static void InitDefaultsDescriptorProto_ReservedRange() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_DescriptorProto_ReservedRange_default_instance_;
    new (ptr) ::google::protobuf::DescriptorProto_ReservedRange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::DescriptorProto_ReservedRange::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDescriptorProto_ReservedRange}, {}};

static void InitDefaultsDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_DescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::DescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::DescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<6> scc_info_DescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 6, InitDefaultsDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base,}};

static void InitDefaultsExtensionRangeOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_ExtensionRangeOptions_default_instance_;
    new (ptr) ::google::protobuf::ExtensionRangeOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::ExtensionRangeOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_ExtensionRangeOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsExtensionRangeOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsFieldDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_FieldDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::FieldDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::FieldDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FieldDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFieldDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base,}};

static void InitDefaultsOneofDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_OneofDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::OneofDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::OneofDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_OneofDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOneofDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base,}};

static void InitDefaultsEnumDescriptorProto_EnumReservedRange() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_EnumDescriptorProto_EnumReservedRange_default_instance_;
    new (ptr) ::google::protobuf::EnumDescriptorProto_EnumReservedRange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEnumDescriptorProto_EnumReservedRange}, {}};

static void InitDefaultsEnumDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_EnumDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::EnumDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::EnumDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_EnumDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEnumDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base,}};

static void InitDefaultsEnumValueDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_EnumValueDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::EnumValueDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::EnumValueDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValueDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base,}};

static void InitDefaultsServiceDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_ServiceDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::ServiceDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::ServiceDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<2> scc_info_ServiceDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsServiceDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base,
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base,}};

static void InitDefaultsMethodDescriptorProto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_MethodDescriptorProto_default_instance_;
    new (ptr) ::google::protobuf::MethodDescriptorProto();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::MethodDescriptorProto::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MethodDescriptorProto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethodDescriptorProto}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base,}};

static void InitDefaultsFileOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_FileOptions_default_instance_;
    new (ptr) ::google::protobuf::FileOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::FileOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FileOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFileOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsMessageOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_MessageOptions_default_instance_;
    new (ptr) ::google::protobuf::MessageOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::MessageOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MessageOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMessageOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsFieldOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_FieldOptions_default_instance_;
    new (ptr) ::google::protobuf::FieldOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::FieldOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FieldOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFieldOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsOneofOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_OneofOptions_default_instance_;
    new (ptr) ::google::protobuf::OneofOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::OneofOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_OneofOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOneofOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsEnumOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_EnumOptions_default_instance_;
    new (ptr) ::google::protobuf::EnumOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::EnumOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsEnumValueOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_EnumValueOptions_default_instance_;
    new (ptr) ::google::protobuf::EnumValueOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::EnumValueOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValueOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsServiceOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_ServiceOptions_default_instance_;
    new (ptr) ::google::protobuf::ServiceOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::ServiceOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_ServiceOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsServiceOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsMethodOptions() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_MethodOptions_default_instance_;
    new (ptr) ::google::protobuf::MethodOptions();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::MethodOptions::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MethodOptions =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethodOptions}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};

static void InitDefaultsUninterpretedOption_NamePart() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_UninterpretedOption_NamePart_default_instance_;
    new (ptr) ::google::protobuf::UninterpretedOption_NamePart();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::UninterpretedOption_NamePart::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUninterpretedOption_NamePart}, {}};

static void InitDefaultsUninterpretedOption() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_UninterpretedOption_default_instance_;
    new (ptr) ::google::protobuf::UninterpretedOption();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::UninterpretedOption::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_UninterpretedOption =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsUninterpretedOption}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base,}};

static void InitDefaultsSourceCodeInfo_Location() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_SourceCodeInfo_Location_default_instance_;
    new (ptr) ::google::protobuf::SourceCodeInfo_Location();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::SourceCodeInfo_Location::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSourceCodeInfo_Location}, {}};

static void InitDefaultsSourceCodeInfo() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_SourceCodeInfo_default_instance_;
    new (ptr) ::google::protobuf::SourceCodeInfo();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::SourceCodeInfo::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_SourceCodeInfo =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsSourceCodeInfo}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base,}};

static void InitDefaultsGeneratedCodeInfo_Annotation() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_GeneratedCodeInfo_Annotation_default_instance_;
    new (ptr) ::google::protobuf::GeneratedCodeInfo_Annotation();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::GeneratedCodeInfo_Annotation::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsGeneratedCodeInfo_Annotation}, {}};

static void InitDefaultsGeneratedCodeInfo() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::google::protobuf::_GeneratedCodeInfo_default_instance_;
    new (ptr) ::google::protobuf::GeneratedCodeInfo();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::google::protobuf::GeneratedCodeInfo::InitAsDefaultInstance();
}

LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_GeneratedCodeInfo =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGeneratedCodeInfo}, {
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base,}};

void InitDefaults() {
  ::google::protobuf::internal::InitSCC(&scc_info_FileDescriptorSet.base);
  ::google::protobuf::internal::InitSCC(&scc_info_FileDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_ExtensionRange.base);
  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_ReservedRange.base);
  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ExtensionRangeOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_FieldDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_OneofDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EnumDescriptorProto_EnumReservedRange.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EnumDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EnumValueDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ServiceDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_MethodDescriptorProto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_FileOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_MessageOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_FieldOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_OneofOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EnumOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EnumValueOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ServiceOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_MethodOptions.base);
  ::google::protobuf::internal::InitSCC(&scc_info_UninterpretedOption_NamePart.base);
  ::google::protobuf::internal::InitSCC(&scc_info_UninterpretedOption.base);
  ::google::protobuf::internal::InitSCC(&scc_info_SourceCodeInfo_Location.base);
  ::google::protobuf::internal::InitSCC(&scc_info_SourceCodeInfo.base);
  ::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo_Annotation.base);
  ::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo.base);
}

::google::protobuf::Metadata file_level_metadata[27];
const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[6];

const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, file_),
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, package_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, dependency_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, public_dependency_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, weak_dependency_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, message_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, enum_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, service_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, extension_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, source_code_info_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorProto, syntax_),
  0,
  1,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  3,
  4,
  2,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, start_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, end_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ExtensionRange, options_),
  1,
  2,
  0,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, start_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto_ReservedRange, end_),
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, field_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, extension_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, nested_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, enum_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, extension_range_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, oneof_decl_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, reserved_range_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DescriptorProto, reserved_name_),
  0,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  1,
  ~0u,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ExtensionRangeOptions, uninterpreted_option_),
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, number_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, label_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, type_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, extendee_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, default_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, oneof_index_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, json_name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldDescriptorProto, options_),
  0,
  6,
  8,
  9,
  2,
  1,
  3,
  7,
  4,
  5,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofDescriptorProto, options_),
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, start_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto_EnumReservedRange, end_),
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, reserved_range_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumDescriptorProto, reserved_name_),
  0,
  ~0u,
  1,
  ~0u,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, number_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueDescriptorProto, options_),
  0,
  2,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, method_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceDescriptorProto, options_),
  0,
  ~0u,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, input_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, output_type_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, options_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, client_streaming_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodDescriptorProto, server_streaming_),
  0,
  1,
  2,
  3,
  4,
  5,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, java_package_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, java_outer_classname_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, java_multiple_files_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, java_generate_equals_and_hash_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, java_string_check_utf8_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, optimize_for_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, go_package_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, cc_generic_services_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, java_generic_services_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, py_generic_services_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, php_generic_services_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, cc_enable_arenas_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, objc_class_prefix_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, csharp_namespace_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, swift_prefix_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, php_class_prefix_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, php_namespace_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, php_metadata_namespace_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, ruby_package_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileOptions, uninterpreted_option_),
  0,
  1,
  10,
  11,
  12,
  19,
  2,
  13,
  14,
  15,
  16,
  17,
  18,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, message_set_wire_format_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, no_standard_descriptor_accessor_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, map_entry_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MessageOptions, uninterpreted_option_),
  0,
  1,
  2,
  3,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, ctype_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, packed_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, jstype_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, lazy_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, weak_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldOptions, uninterpreted_option_),
  0,
  1,
  5,
  2,
  3,
  4,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::OneofOptions, uninterpreted_option_),
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumOptions, allow_alias_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumOptions, uninterpreted_option_),
  0,
  1,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::EnumValueOptions, uninterpreted_option_),
  0,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::ServiceOptions, uninterpreted_option_),
  0,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodOptions, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodOptions, _internal_metadata_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodOptions, _extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodOptions, deprecated_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodOptions, idempotency_level_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::MethodOptions, uninterpreted_option_),
  0,
  1,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, name_part_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption_NamePart, is_extension_),
  0,
  1,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, name_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, identifier_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, positive_int_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, negative_int_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, double_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, string_value_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::UninterpretedOption, aggregate_value_),
  ~0u,
  0,
  3,
  4,
  5,
  1,
  2,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, path_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, span_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, leading_comments_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, trailing_comments_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo_Location, leading_detached_comments_),
  ~0u,
  ~0u,
  0,
  1,
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceCodeInfo, location_),
  ~0u,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, path_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, source_file_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, begin_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo_Annotation, end_),
  ~0u,
  0,
  1,
  2,
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, _has_bits_),
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::GeneratedCodeInfo, annotation_),
  ~0u,
};
static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
  { 0, 6, sizeof(::google::protobuf::FileDescriptorSet)},
  { 7, 24, sizeof(::google::protobuf::FileDescriptorProto)},
  { 36, 44, sizeof(::google::protobuf::DescriptorProto_ExtensionRange)},
  { 47, 54, sizeof(::google::protobuf::DescriptorProto_ReservedRange)},
  { 56, 71, sizeof(::google::protobuf::DescriptorProto)},
  { 81, 87, sizeof(::google::protobuf::ExtensionRangeOptions)},
  { 88, 103, sizeof(::google::protobuf::FieldDescriptorProto)},
  { 113, 120, sizeof(::google::protobuf::OneofDescriptorProto)},
  { 122, 129, sizeof(::google::protobuf::EnumDescriptorProto_EnumReservedRange)},
  { 131, 141, sizeof(::google::protobuf::EnumDescriptorProto)},
  { 146, 154, sizeof(::google::protobuf::EnumValueDescriptorProto)},
  { 157, 165, sizeof(::google::protobuf::ServiceDescriptorProto)},
  { 168, 179, sizeof(::google::protobuf::MethodDescriptorProto)},
  { 185, 211, sizeof(::google::protobuf::FileOptions)},
  { 232, 242, sizeof(::google::protobuf::MessageOptions)},
  { 247, 259, sizeof(::google::protobuf::FieldOptions)},
  { 266, 272, sizeof(::google::protobuf::OneofOptions)},
  { 273, 281, sizeof(::google::protobuf::EnumOptions)},
  { 284, 291, sizeof(::google::protobuf::EnumValueOptions)},
  { 293, 300, sizeof(::google::protobuf::ServiceOptions)},
  { 302, 310, sizeof(::google::protobuf::MethodOptions)},
  { 313, 320, sizeof(::google::protobuf::UninterpretedOption_NamePart)},
  { 322, 334, sizeof(::google::protobuf::UninterpretedOption)},
  { 341, 351, sizeof(::google::protobuf::SourceCodeInfo_Location)},
  { 356, 362, sizeof(::google::protobuf::SourceCodeInfo)},
  { 363, 372, sizeof(::google::protobuf::GeneratedCodeInfo_Annotation)},
  { 376, 382, sizeof(::google::protobuf::GeneratedCodeInfo)},
};

static ::google::protobuf::Message const * const file_default_instances[] = {
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FileDescriptorSet_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FileDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_DescriptorProto_ExtensionRange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_DescriptorProto_ReservedRange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_DescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ExtensionRangeOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_OneofDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_EnumDescriptorProto_EnumReservedRange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_EnumDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_EnumValueDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ServiceDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_MethodDescriptorProto_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FileOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_MessageOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_OneofOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_EnumOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_EnumValueOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ServiceOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_MethodOptions_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_UninterpretedOption_NamePart_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_UninterpretedOption_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_SourceCodeInfo_Location_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_SourceCodeInfo_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_GeneratedCodeInfo_Annotation_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_GeneratedCodeInfo_default_instance_),
};

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

void protobuf_AssignDescriptorsOnce() {
  static ::google::protobuf::internal::once_flag once;
  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
}

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

void AddDescriptorsImpl() {
  InitDefaults();
  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
      "\n google/protobuf/descriptor.proto\022\017goog"
      "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
      "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
      "roto\"\333\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
      "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
      "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
      "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
      "le.protobuf.DescriptorProto\0227\n\tenum_type"
      "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
      "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
      "ServiceDescriptorProto\0228\n\textension\030\007 \003("
      "\0132%.google.protobuf.FieldDescriptorProto"
      "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
      "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
      "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001"
      "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005"
      "field\030\002 \003(\0132%.google.protobuf.FieldDescr"
      "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p"
      "rotobuf.FieldDescriptorProto\0225\n\013nested_t"
      "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr"
      "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf"
      ".EnumDescriptorProto\022H\n\017extension_range\030"
      "\005 \003(\0132/.google.protobuf.DescriptorProto."
      "ExtensionRange\0229\n\noneof_decl\030\010 \003(\0132%.goo"
      "gle.protobuf.OneofDescriptorProto\0220\n\007opt"
      "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti"
      "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro"
      "tobuf.DescriptorProto.ReservedRange\022\025\n\rr"
      "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005"
      "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001("
      "\0132&.google.protobuf.ExtensionRangeOption"
      "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end"
      "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint"
      "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
      ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\274\005\n\024Fiel"
      "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number"
      "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf."
      "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016"
      "2*.google.protobuf.FieldDescriptorProto."
      "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001("
      "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030"
      "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001("
      "\0132\035.google.protobuf.FieldOptions\"\266\002\n\004Typ"
      "e\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTY"
      "PE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT3"
      "2\020\005\022\020\n\014TYPE_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\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYP"
      "E_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_"
      "SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LA"
      "BEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LA"
      "BEL_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014"
      "\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.p"
      "rotobuf.OneofOptions\"\244\002\n\023EnumDescriptorP"
      "roto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).goog"
      "le.protobuf.EnumValueDescriptorProto\022-\n\007"
      "options\030\003 \001(\0132\034.google.protobuf.EnumOpti"
      "ons\022N\n\016reserved_range\030\004 \003(\01326.google.pro"
      "tobuf.EnumDescriptorProto.EnumReservedRa"
      "nge\022\025\n\rreserved_name\030\005 \003(\t\032/\n\021EnumReserv"
      "edRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030E"
      "numValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n"
      "\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google."
      "protobuf.EnumValueOptions\"\220\001\n\026ServiceDes"
      "criptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003"
      "(\0132&.google.protobuf.MethodDescriptorPro"
      "to\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Se"
      "rviceOptions\"\301\001\n\025MethodDescriptorProto\022\014"
      "\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013outp"
      "ut_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google."
      "protobuf.MethodOptions\022\037\n\020client_streami"
      "ng\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001("
      "\010:\005false\"\246\006\n\013FileOptions\022\024\n\014java_package"
      "\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023"
      "java_multiple_files\030\n \001(\010:\005false\022)\n\035java"
      "_generate_equals_and_hash\030\024 \001(\010B\002\030\001\022%\n\026j"
      "ava_string_check_utf8\030\033 \001(\010:\005false\022F\n\014op"
      "timize_for\030\t \001(\0162).google.protobuf.FileO"
      "ptions.OptimizeMode:\005SPEED\022\022\n\ngo_package"
      "\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fal"
      "se\022$\n\025java_generic_services\030\021 \001(\010:\005false"
      "\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022#\n\024"
      "php_generic_services\030* \001(\010:\005false\022\031\n\ndep"
      "recated\030\027 \001(\010:\005false\022\037\n\020cc_enable_arenas"
      "\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030$ \001(\t"
      "\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014swift_pref"
      "ix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001(\t\022\025\n\rph"
      "p_namespace\030) \001(\t\022\036\n\026php_metadata_namesp"
      "ace\030, \001(\t\022\024\n\014ruby_package\030- \001(\t\022C\n\024unint"
      "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
      ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005"
      "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003"
      "*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027"
      "message_set_wire_format\030\001 \001(\010:\005false\022.\n\037"
      "no_standard_descriptor_accessor\030\002 \001(\010:\005f"
      "alse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_e"
      "ntry\030\007 \001(\010\022C\n\024uninterpreted_option\030\347\007 \003("
      "\0132$.google.protobuf.UninterpretedOption*"
      "\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022"
      ":\n\005ctype\030\001 \001(\0162#.google.protobuf.FieldOp"
      "tions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006j"
      "stype\030\006 \001(\0162$.google.protobuf.FieldOptio"
      "ns.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fals"
      "e\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001"
      "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013"
      "2$.google.protobuf.UninterpretedOption\"/"
      "\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_"
      "PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_S"
      "TRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\""
      "^\n\014OneofOptions\022C\n\024uninterpreted_option\030"
      "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
      "tion*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow"
      "_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
      "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
      "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J"
      "\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030"
      "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 "
      "\003(\0132$.google.protobuf.UninterpretedOptio"
      "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec"
      "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio"
      "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
      "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd"
      "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le"
      "vel\030\" \001(\0162/.google.protobuf.MethodOption"
      "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022"
      "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
      "protobuf.UninterpretedOption\"P\n\020Idempote"
      "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_"
      "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200"
      "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132"
      "-.google.protobuf.UninterpretedOption.Na"
      "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi"
      "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val"
      "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string"
      "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n"
      "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten"
      "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio"
      "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo"
      ".Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001"
      "\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003"
      " \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031leadi"
      "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated"
      "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr"
      "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA"
      "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi"
      "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\217\001\n"
      "\023com.google.protobufB\020DescriptorProtosH\001"
      "Z>github.com/golang/protobuf/protoc-gen-"
      "go/descriptor;descriptor\370\001\001\242\002\003GPB\252\002\032Goog"
      "le.Protobuf.Reflection"
  };
  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
      descriptor, 6022);
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
}

void AddDescriptors() {
  static ::google::protobuf::internal::once_flag once;
  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
}
// Force AddDescriptors() to be called at dynamic initialization time.
struct StaticDescriptorInitializer {
  StaticDescriptorInitializer() {
    AddDescriptors();
  }
} static_descriptor_initializer;
}  // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto
namespace google {
namespace protobuf {
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[0];
}
bool FieldDescriptorProto_Type_IsValid(int value) {
  switch (value) {
    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 FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
const int FieldDescriptorProto::Type_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[1];
}
bool FieldDescriptorProto_Label_IsValid(int value) {
  switch (value) {
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
const int FieldDescriptorProto::Label_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[2];
}
bool FileOptions_OptimizeMode_IsValid(int value) {
  switch (value) {
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const FileOptions_OptimizeMode FileOptions::SPEED;
const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
const int FileOptions::OptimizeMode_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[3];
}
bool FieldOptions_CType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const FieldOptions_CType FieldOptions::STRING;
const FieldOptions_CType FieldOptions::CORD;
const FieldOptions_CType FieldOptions::STRING_PIECE;
const FieldOptions_CType FieldOptions::CType_MIN;
const FieldOptions_CType FieldOptions::CType_MAX;
const int FieldOptions::CType_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor() {
  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[4];
}
bool FieldOptions_JSType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const FieldOptions_JSType FieldOptions::JS_NORMAL;
const FieldOptions_JSType FieldOptions::JS_STRING;
const FieldOptions_JSType FieldOptions::JS_NUMBER;
const FieldOptions_JSType FieldOptions::JSType_MIN;
const FieldOptions_JSType FieldOptions::JSType_MAX;
const int FieldOptions::JSType_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor() {
  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[5];
}
bool MethodOptions_IdempotencyLevel_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENCY_UNKNOWN;
const MethodOptions_IdempotencyLevel MethodOptions::NO_SIDE_EFFECTS;
const MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENT;
const MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MIN;
const MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MAX;
const int MethodOptions::IdempotencyLevel_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

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

void FileDescriptorSet::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FileDescriptorSet::kFileFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

FileDescriptorSet::FileDescriptorSet()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorSet.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet)
}
FileDescriptorSet::FileDescriptorSet(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  file_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorSet.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet)
}
FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      file_(from.file_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
}

void FileDescriptorSet::SharedCtor() {
}

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

void FileDescriptorSet::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const FileDescriptorSet& FileDescriptorSet::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorSet.base);
  return *internal_default_instance();
}


void FileDescriptorSet::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  file_.Clear();
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool FileDescriptorSet::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.FileDescriptorSet)
  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)) {
      // repeated .google.protobuf.FileDescriptorProto file = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_file()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorSet)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorSet)
  return false;
#undef DO_
}

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

  // repeated .google.protobuf.FileDescriptorProto file = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->file_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1,
      this->file(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet)
}

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

  // repeated .google.protobuf.FileDescriptorProto file = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->file_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->file(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.FileDescriptorProto file = 1;
  {
    unsigned int count = static_cast<unsigned int>(this->file_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->file(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  file_.MergeFrom(from.file_);
}

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

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

bool FileDescriptorSet::IsInitialized() const {
  if (!::google::protobuf::internal::AllAreInitialized(this->file())) return false;
  return true;
}

void FileDescriptorSet::Swap(FileDescriptorSet* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    FileDescriptorSet* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void FileDescriptorSet::UnsafeArenaSwap(FileDescriptorSet* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) {
  using std::swap;
  CastToBase(&file_)->InternalSwap(CastToBase(&other->file_));
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void FileDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_FileDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::FileOptions*>(
      ::google::protobuf::FileOptions::internal_default_instance());
  ::google::protobuf::_FileDescriptorProto_default_instance_._instance.get_mutable()->source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(
      ::google::protobuf::SourceCodeInfo::internal_default_instance());
}
void FileDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::FileOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
}
void FileDescriptorProto::unsafe_arena_set_allocated_source_code_info(
    ::google::protobuf::SourceCodeInfo* source_code_info) {
  if (GetArenaNoVirtual() == NULL) {
    delete source_code_info_;
  }
  source_code_info_ = source_code_info;
  if (source_code_info) {
    set_has_source_code_info();
  } else {
    clear_has_source_code_info();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FileDescriptorProto::kNameFieldNumber;
const int FileDescriptorProto::kPackageFieldNumber;
const int FileDescriptorProto::kDependencyFieldNumber;
const int FileDescriptorProto::kPublicDependencyFieldNumber;
const int FileDescriptorProto::kWeakDependencyFieldNumber;
const int FileDescriptorProto::kMessageTypeFieldNumber;
const int FileDescriptorProto::kEnumTypeFieldNumber;
const int FileDescriptorProto::kServiceFieldNumber;
const int FileDescriptorProto::kExtensionFieldNumber;
const int FileDescriptorProto::kOptionsFieldNumber;
const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
const int FileDescriptorProto::kSyntaxFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

FileDescriptorProto::FileDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto)
}
FileDescriptorProto::FileDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  dependency_(arena),
  message_type_(arena),
  enum_type_(arena),
  service_(arena),
  extension_(arena),
  public_dependency_(arena),
  weak_dependency_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto)
}
FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      dependency_(from.dependency_),
      message_type_(from.message_type_),
      enum_type_(from.enum_type_),
      service_(from.service_),
      extension_(from.extension_),
      public_dependency_(from.public_dependency_),
      weak_dependency_(from.weak_dependency_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_package()) {
    package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.package(),
      GetArenaNoVirtual());
  }
  syntax_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_syntax()) {
    syntax_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.syntax(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::FileOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  if (from.has_source_code_info()) {
    source_code_info_ = new ::google::protobuf::SourceCodeInfo(*from.source_code_info_);
  } else {
    source_code_info_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
}

void FileDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  syntax_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&options_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&source_code_info_) -
      reinterpret_cast<char*>(&options_)) + sizeof(source_code_info_));
}

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

void FileDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  syntax_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
  if (this != internal_default_instance()) delete source_code_info_;
}

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

const FileDescriptorProto& FileDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base);
  return *internal_default_instance();
}


void FileDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  dependency_.Clear();
  message_type_.Clear();
  enum_type_.Clear();
  service_.Clear();
  extension_.Clear();
  public_dependency_.Clear();
  weak_dependency_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 31u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      package_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      syntax_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
    if (cached_has_bits & 0x00000010u) {
      GOOGLE_DCHECK(source_code_info_ != NULL);
      source_code_info_->Clear();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool FileDescriptorProto::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.FileDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string package = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->package().data(), static_cast<int>(this->package().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileDescriptorProto.package");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated string dependency = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_dependency()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->dependency(this->dependency_size() - 1).data(),
            static_cast<int>(this->dependency(this->dependency_size() - 1).length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileDescriptorProto.dependency");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.DescriptorProto message_type = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_message_type()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_enum_type()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_service()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_extension()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.FileOptions options = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_source_code_info()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated int32 public_dependency = 10;
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 80u, input, this->mutable_public_dependency())));
        } else if (
            static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_public_dependency())));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated int32 weak_dependency = 11;
      case 11: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(88u /* 88 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 88u, input, this->mutable_weak_dependency())));
        } else if (
            static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_weak_dependency())));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string syntax = 12;
      case 12: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(98u /* 98 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_syntax()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->syntax().data(), static_cast<int>(this->syntax().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileDescriptorProto.syntax");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // optional string package = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->package().data(), static_cast<int>(this->package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.package");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->package(), output);
  }

  // repeated string dependency = 3;
  for (int i = 0, n = this->dependency_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->dependency(i).data(), static_cast<int>(this->dependency(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.dependency");
    ::google::protobuf::internal::WireFormatLite::WriteString(
      3, this->dependency(i), output);
  }

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

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5,
      this->enum_type(static_cast<int>(i)),
      output);
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->service_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6,
      this->service(static_cast<int>(i)),
      output);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      7,
      this->extension(static_cast<int>(i)),
      output);
  }

  // optional .google.protobuf.FileOptions options = 8;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8, this->_internal_options(), output);
  }

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      9, this->_internal_source_code_info(), output);
  }

  // repeated int32 public_dependency = 10;
  for (int i = 0, n = this->public_dependency_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(
      10, this->public_dependency(i), output);
  }

  // repeated int32 weak_dependency = 11;
  for (int i = 0, n = this->weak_dependency_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(
      11, this->weak_dependency(i), output);
  }

  // optional string syntax = 12;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->syntax().data(), static_cast<int>(this->syntax().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.syntax");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      12, this->syntax(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional string package = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->package().data(), static_cast<int>(this->package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.package");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->package(), target);
  }

  // repeated string dependency = 3;
  for (int i = 0, n = this->dependency_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->dependency(i).data(), static_cast<int>(this->dependency(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.dependency");
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(3, this->dependency(i), target);
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->message_type_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, this->message_type(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        5, this->enum_type(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->service_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        6, this->service(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        7, this->extension(static_cast<int>(i)), deterministic, target);
  }

  // optional .google.protobuf.FileOptions options = 8;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        8, this->_internal_options(), deterministic, target);
  }

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        9, this->_internal_source_code_info(), deterministic, target);
  }

  // repeated int32 public_dependency = 10;
  target = ::google::protobuf::internal::WireFormatLite::
    WriteInt32ToArray(10, this->public_dependency_, target);

  // repeated int32 weak_dependency = 11;
  target = ::google::protobuf::internal::WireFormatLite::
    WriteInt32ToArray(11, this->weak_dependency_, target);

  // optional string syntax = 12;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->syntax().data(), static_cast<int>(this->syntax().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.syntax");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        12, this->syntax(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated string dependency = 3;
  total_size += 1 *
      ::google::protobuf::internal::FromIntSize(this->dependency_size());
  for (int i = 0, n = this->dependency_size(); i < n; i++) {
    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
      this->dependency(i));
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  {
    unsigned int count = static_cast<unsigned int>(this->message_type_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->message_type(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  {
    unsigned int count = static_cast<unsigned int>(this->enum_type_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->enum_type(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  {
    unsigned int count = static_cast<unsigned int>(this->service_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->service(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  {
    unsigned int count = static_cast<unsigned int>(this->extension_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->extension(static_cast<int>(i)));
    }
  }

  // repeated int32 public_dependency = 10;
  {
    size_t data_size = ::google::protobuf::internal::WireFormatLite::
      Int32Size(this->public_dependency_);
    total_size += 1 *
                  ::google::protobuf::internal::FromIntSize(this->public_dependency_size());
    total_size += data_size;
  }

  // repeated int32 weak_dependency = 11;
  {
    size_t data_size = ::google::protobuf::internal::WireFormatLite::
      Int32Size(this->weak_dependency_);
    total_size += 1 *
                  ::google::protobuf::internal::FromIntSize(this->weak_dependency_size());
    total_size += data_size;
  }

  if (_has_bits_[0 / 32] & 31u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional string package = 2;
    if (has_package()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->package());
    }

    // optional string syntax = 12;
    if (has_syntax()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->syntax());
    }

    // optional .google.protobuf.FileOptions options = 8;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

    // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    if (has_source_code_info()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *source_code_info_);
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  dependency_.MergeFrom(from.dependency_);
  message_type_.MergeFrom(from.message_type_);
  enum_type_.MergeFrom(from.enum_type_);
  service_.MergeFrom(from.service_);
  extension_.MergeFrom(from.extension_);
  public_dependency_.MergeFrom(from.public_dependency_);
  weak_dependency_.MergeFrom(from.weak_dependency_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 31u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      set_package(from.package());
    }
    if (cached_has_bits & 0x00000004u) {
      set_syntax(from.syntax());
    }
    if (cached_has_bits & 0x00000008u) {
      mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
    }
    if (cached_has_bits & 0x00000010u) {
      mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
    }
  }
}

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

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

bool FileDescriptorProto::IsInitialized() const {
  if (!::google::protobuf::internal::AllAreInitialized(this->message_type())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->service())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void FileDescriptorProto::Swap(FileDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    FileDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void FileDescriptorProto::UnsafeArenaSwap(FileDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) {
  using std::swap;
  dependency_.InternalSwap(CastToBase(&other->dependency_));
  CastToBase(&message_type_)->InternalSwap(CastToBase(&other->message_type_));
  CastToBase(&enum_type_)->InternalSwap(CastToBase(&other->enum_type_));
  CastToBase(&service_)->InternalSwap(CastToBase(&other->service_));
  CastToBase(&extension_)->InternalSwap(CastToBase(&other->extension_));
  public_dependency_.InternalSwap(&other->public_dependency_);
  weak_dependency_.InternalSwap(&other->weak_dependency_);
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  package_.Swap(&other->package_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  syntax_.Swap(&other->syntax_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(source_code_info_, other->source_code_info_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
  ::google::protobuf::_DescriptorProto_ExtensionRange_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::ExtensionRangeOptions*>(
      ::google::protobuf::ExtensionRangeOptions::internal_default_instance());
}
void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options(
    ::google::protobuf::ExtensionRangeOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int DescriptorProto_ExtensionRange::kStartFieldNumber;
const int DescriptorProto_ExtensionRange::kEndFieldNumber;
const int DescriptorProto_ExtensionRange::kOptionsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange)
}
DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange)
}
DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_options()) {
    options_ = new ::google::protobuf::ExtensionRangeOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  ::memcpy(&start_, &from.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
    reinterpret_cast<char*>(&start_)) + sizeof(end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
}

void DescriptorProto_ExtensionRange::SharedCtor() {
  ::memset(&options_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&end_) -
      reinterpret_cast<char*>(&options_)) + sizeof(end_));
}

DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
  SharedDtor();
}

void DescriptorProto_ExtensionRange::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  if (this != internal_default_instance()) delete options_;
}

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

const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base);
  return *internal_default_instance();
}


void DescriptorProto_ExtensionRange::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    GOOGLE_DCHECK(options_ != NULL);
    options_->Clear();
  }
  if (cached_has_bits & 6u) {
    ::memset(&start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&end_) -
        reinterpret_cast<char*>(&start_)) + sizeof(end_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool DescriptorProto_ExtensionRange::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.DescriptorProto.ExtensionRange)
  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)) {
      // optional int32 start = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_start();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &start_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 end = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_end();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.ExtensionRangeOptions options = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto.ExtensionRange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto.ExtensionRange)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
  }

  // optional .google.protobuf.ExtensionRangeOptions options = 3;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->_internal_options(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
  }

  // optional .google.protobuf.ExtensionRangeOptions options = 3;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->_internal_options(), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 7u) {
    // optional .google.protobuf.ExtensionRangeOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

    // optional int32 start = 1;
    if (has_start()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->start());
    }

    // optional int32 end = 2;
    if (has_end()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      mutable_options()->::google::protobuf::ExtensionRangeOptions::MergeFrom(from.options());
    }
    if (cached_has_bits & 0x00000002u) {
      start_ = from.start_;
    }
    if (cached_has_bits & 0x00000004u) {
      end_ = from.end_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool DescriptorProto_ExtensionRange::IsInitialized() const {
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    DescriptorProto_ExtensionRange* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void DescriptorProto_ExtensionRange::UnsafeArenaSwap(DescriptorProto_ExtensionRange* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) {
  using std::swap;
  swap(options_, other->options_);
  swap(start_, other->start_);
  swap(end_, other->end_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void DescriptorProto_ReservedRange::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int DescriptorProto_ReservedRange::kStartFieldNumber;
const int DescriptorProto_ReservedRange::kEndFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

DescriptorProto_ReservedRange::DescriptorProto_ReservedRange()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ReservedRange)
}
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange)
}
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&start_, &from.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
    reinterpret_cast<char*>(&start_)) + sizeof(end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange)
}

void DescriptorProto_ReservedRange::SharedCtor() {
  ::memset(&start_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&end_) -
      reinterpret_cast<char*>(&start_)) + sizeof(end_));
}

DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() {
  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange)
  SharedDtor();
}

void DescriptorProto_ReservedRange::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base);
  return *internal_default_instance();
}


void DescriptorProto_ReservedRange::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    ::memset(&start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&end_) -
        reinterpret_cast<char*>(&start_)) + sizeof(end_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool DescriptorProto_ReservedRange::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.DescriptorProto.ReservedRange)
  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)) {
      // optional int32 start = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_start();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &start_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 end = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_end();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto.ReservedRange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto.ReservedRange)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ReservedRange)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 3u) {
    // optional int32 start = 1;
    if (has_start()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->start());
    }

    // optional int32 end = 2;
    if (has_end()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      start_ = from.start_;
    }
    if (cached_has_bits & 0x00000002u) {
      end_ = from.end_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

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

void DescriptorProto_ReservedRange::Swap(DescriptorProto_ReservedRange* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    DescriptorProto_ReservedRange* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void DescriptorProto_ReservedRange::UnsafeArenaSwap(DescriptorProto_ReservedRange* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) {
  using std::swap;
  swap(start_, other->start_);
  swap(end_, other->end_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void DescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_DescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::MessageOptions*>(
      ::google::protobuf::MessageOptions::internal_default_instance());
}
void DescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::MessageOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int DescriptorProto::kNameFieldNumber;
const int DescriptorProto::kFieldFieldNumber;
const int DescriptorProto::kExtensionFieldNumber;
const int DescriptorProto::kNestedTypeFieldNumber;
const int DescriptorProto::kEnumTypeFieldNumber;
const int DescriptorProto::kExtensionRangeFieldNumber;
const int DescriptorProto::kOneofDeclFieldNumber;
const int DescriptorProto::kOptionsFieldNumber;
const int DescriptorProto::kReservedRangeFieldNumber;
const int DescriptorProto::kReservedNameFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

DescriptorProto::DescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto)
}
DescriptorProto::DescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  field_(arena),
  nested_type_(arena),
  enum_type_(arena),
  extension_range_(arena),
  extension_(arena),
  oneof_decl_(arena),
  reserved_range_(arena),
  reserved_name_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto)
}
DescriptorProto::DescriptorProto(const DescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      field_(from.field_),
      nested_type_(from.nested_type_),
      enum_type_(from.enum_type_),
      extension_range_(from.extension_range_),
      extension_(from.extension_),
      oneof_decl_(from.oneof_decl_),
      reserved_range_(from.reserved_range_),
      reserved_name_(from.reserved_name_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::MessageOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
}

void DescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  options_ = NULL;
}

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

void DescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const DescriptorProto& DescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base);
  return *internal_default_instance();
}


void DescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  field_.Clear();
  nested_type_.Clear();
  enum_type_.Clear();
  extension_range_.Clear();
  extension_.Clear();
  oneof_decl_.Clear();
  reserved_range_.Clear();
  reserved_name_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool DescriptorProto::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.DescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.DescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.FieldDescriptorProto field = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_field()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.DescriptorProto nested_type = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_nested_type()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_enum_type()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_extension_range()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.FieldDescriptorProto extension = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_extension()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.MessageOptions options = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_oneof_decl()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_reserved_range()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated string reserved_name = 10;
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_reserved_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->reserved_name(this->reserved_name_size() - 1).data(),
            static_cast<int>(this->reserved_name(this->reserved_name_size() - 1).length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.DescriptorProto.reserved_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.DescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

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

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

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

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->extension_range_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5,
      this->extension_range(static_cast<int>(i)),
      output);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6,
      this->extension(static_cast<int>(i)),
      output);
  }

  // optional .google.protobuf.MessageOptions options = 7;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      7, this->_internal_options(), output);
  }

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->oneof_decl_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8,
      this->oneof_decl(static_cast<int>(i)),
      output);
  }

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->reserved_range_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      9,
      this->reserved_range(static_cast<int>(i)),
      output);
  }

  // repeated string reserved_name = 10;
  for (int i = 0, n = this->reserved_name_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->reserved_name(i).data(), static_cast<int>(this->reserved_name(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.DescriptorProto.reserved_name");
    ::google::protobuf::internal::WireFormatLite::WriteString(
      10, this->reserved_name(i), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.DescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->field_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->field(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->nested_type_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->nested_type(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->enum_type_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, this->enum_type(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->extension_range_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        5, this->extension_range(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->extension_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        6, this->extension(static_cast<int>(i)), deterministic, target);
  }

  // optional .google.protobuf.MessageOptions options = 7;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        7, this->_internal_options(), deterministic, target);
  }

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->oneof_decl_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        8, this->oneof_decl(static_cast<int>(i)), deterministic, target);
  }

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->reserved_range_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        9, this->reserved_range(static_cast<int>(i)), deterministic, target);
  }

  // repeated string reserved_name = 10;
  for (int i = 0, n = this->reserved_name_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->reserved_name(i).data(), static_cast<int>(this->reserved_name(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.DescriptorProto.reserved_name");
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(10, this->reserved_name(i), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  {
    unsigned int count = static_cast<unsigned int>(this->field_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->field(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  {
    unsigned int count = static_cast<unsigned int>(this->nested_type_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->nested_type(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  {
    unsigned int count = static_cast<unsigned int>(this->enum_type_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->enum_type(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  {
    unsigned int count = static_cast<unsigned int>(this->extension_range_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->extension_range(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  {
    unsigned int count = static_cast<unsigned int>(this->extension_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->extension(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  {
    unsigned int count = static_cast<unsigned int>(this->oneof_decl_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->oneof_decl(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  {
    unsigned int count = static_cast<unsigned int>(this->reserved_range_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->reserved_range(static_cast<int>(i)));
    }
  }

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

  if (_has_bits_[0 / 32] & 3u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.MessageOptions options = 7;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  field_.MergeFrom(from.field_);
  nested_type_.MergeFrom(from.nested_type_);
  enum_type_.MergeFrom(from.enum_type_);
  extension_range_.MergeFrom(from.extension_range_);
  extension_.MergeFrom(from.extension_);
  oneof_decl_.MergeFrom(from.oneof_decl_);
  reserved_range_.MergeFrom(from.reserved_range_);
  reserved_name_.MergeFrom(from.reserved_name_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
    }
  }
}

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

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

bool DescriptorProto::IsInitialized() const {
  if (!::google::protobuf::internal::AllAreInitialized(this->field())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->extension_range())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
  if (!::google::protobuf::internal::AllAreInitialized(this->oneof_decl())) return false;
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void DescriptorProto::Swap(DescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    DescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void DescriptorProto::UnsafeArenaSwap(DescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void DescriptorProto::InternalSwap(DescriptorProto* other) {
  using std::swap;
  CastToBase(&field_)->InternalSwap(CastToBase(&other->field_));
  CastToBase(&nested_type_)->InternalSwap(CastToBase(&other->nested_type_));
  CastToBase(&enum_type_)->InternalSwap(CastToBase(&other->enum_type_));
  CastToBase(&extension_range_)->InternalSwap(CastToBase(&other->extension_range_));
  CastToBase(&extension_)->InternalSwap(CastToBase(&other->extension_));
  CastToBase(&oneof_decl_)->InternalSwap(CastToBase(&other->oneof_decl_));
  CastToBase(&reserved_range_)->InternalSwap(CastToBase(&other->reserved_range_));
  reserved_name_.InternalSwap(CastToBase(&other->reserved_name_));
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void ExtensionRangeOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ExtensionRangeOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ExtensionRangeOptions::ExtensionRangeOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.ExtensionRangeOptions)
}
ExtensionRangeOptions::ExtensionRangeOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions)
}
ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions)
}

void ExtensionRangeOptions::SharedCtor() {
}

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

void ExtensionRangeOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const ExtensionRangeOptions& ExtensionRangeOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base);
  return *internal_default_instance();
}


void ExtensionRangeOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool ExtensionRangeOptions::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.ExtensionRangeOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.ExtensionRangeOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.ExtensionRangeOptions)
  return false;
#undef DO_
}

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

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.ExtensionRangeOptions)
}

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

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ExtensionRangeOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
}

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

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

bool ExtensionRangeOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void ExtensionRangeOptions::Swap(ExtensionRangeOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    ExtensionRangeOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void ExtensionRangeOptions::UnsafeArenaSwap(ExtensionRangeOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void FieldDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_FieldDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::FieldOptions*>(
      ::google::protobuf::FieldOptions::internal_default_instance());
}
void FieldDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::FieldOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FieldDescriptorProto::kNameFieldNumber;
const int FieldDescriptorProto::kNumberFieldNumber;
const int FieldDescriptorProto::kLabelFieldNumber;
const int FieldDescriptorProto::kTypeFieldNumber;
const int FieldDescriptorProto::kTypeNameFieldNumber;
const int FieldDescriptorProto::kExtendeeFieldNumber;
const int FieldDescriptorProto::kDefaultValueFieldNumber;
const int FieldDescriptorProto::kOneofIndexFieldNumber;
const int FieldDescriptorProto::kJsonNameFieldNumber;
const int FieldDescriptorProto::kOptionsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

FieldDescriptorProto::FieldDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto)
}
FieldDescriptorProto::FieldDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto)
}
FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_extendee()) {
    extendee_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.extendee(),
      GetArenaNoVirtual());
  }
  type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_type_name()) {
    type_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name(),
      GetArenaNoVirtual());
  }
  default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_default_value()) {
    default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value(),
      GetArenaNoVirtual());
  }
  json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_json_name()) {
    json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::FieldOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  ::memcpy(&number_, &from.number_,
    static_cast<size_t>(reinterpret_cast<char*>(&type_) -
    reinterpret_cast<char*>(&number_)) + sizeof(type_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
}

void FieldDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&options_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&oneof_index_) -
      reinterpret_cast<char*>(&options_)) + sizeof(oneof_index_));
  label_ = 1;
  type_ = 1;
}

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

void FieldDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  extendee_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  type_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  default_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base);
  return *internal_default_instance();
}


void FieldDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 63u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      extendee_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      type_name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      default_value_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000010u) {
      json_name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000020u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  if (cached_has_bits & 192u) {
    ::memset(&number_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&oneof_index_) -
        reinterpret_cast<char*>(&number_)) + sizeof(oneof_index_));
  }
  if (cached_has_bits & 768u) {
    label_ = 1;
    type_ = 1;
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool FieldDescriptorProto::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.FieldDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FieldDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string extendee = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_extendee()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->extendee().data(), static_cast<int>(this->extendee().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FieldDescriptorProto.extendee");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 number = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_number();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &number_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
            set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                4, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
            set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                5, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string type_name = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_type_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->type_name().data(), static_cast<int>(this->type_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FieldDescriptorProto.type_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string default_value = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_default_value()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->default_value().data(), static_cast<int>(this->default_value().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FieldDescriptorProto.default_value");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.FieldOptions options = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 oneof_index = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
          set_has_oneof_index();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &oneof_index_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string json_name = 10;
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_json_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->json_name().data(), static_cast<int>(this->json_name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FieldDescriptorProto.json_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.FieldDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.FieldDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // optional string extendee = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->extendee().data(), static_cast<int>(this->extendee().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.extendee");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->extendee(), output);
  }

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

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  if (cached_has_bits & 0x00000100u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      4, this->label(), output);
  }

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  if (cached_has_bits & 0x00000200u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      5, this->type(), output);
  }

  // optional string type_name = 6;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->type_name().data(), static_cast<int>(this->type_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.type_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      6, this->type_name(), output);
  }

  // optional string default_value = 7;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->default_value().data(), static_cast<int>(this->default_value().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.default_value");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      7, this->default_value(), output);
  }

  // optional .google.protobuf.FieldOptions options = 8;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8, this->_internal_options(), output);
  }

  // optional int32 oneof_index = 9;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->oneof_index(), output);
  }

  // optional string json_name = 10;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->json_name().data(), static_cast<int>(this->json_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.json_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      10, this->json_name(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional string extendee = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->extendee().data(), static_cast<int>(this->extendee().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.extendee");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->extendee(), target);
  }

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

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  if (cached_has_bits & 0x00000100u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      4, this->label(), target);
  }

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  if (cached_has_bits & 0x00000200u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      5, this->type(), target);
  }

  // optional string type_name = 6;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->type_name().data(), static_cast<int>(this->type_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.type_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        6, this->type_name(), target);
  }

  // optional string default_value = 7;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->default_value().data(), static_cast<int>(this->default_value().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.default_value");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        7, this->default_value(), target);
  }

  // optional .google.protobuf.FieldOptions options = 8;
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        8, this->_internal_options(), deterministic, target);
  }

  // optional int32 oneof_index = 9;
  if (cached_has_bits & 0x00000080u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->oneof_index(), target);
  }

  // optional string json_name = 10;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->json_name().data(), static_cast<int>(this->json_name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.json_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        10, this->json_name(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 255u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional string extendee = 2;
    if (has_extendee()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->extendee());
    }

    // optional string type_name = 6;
    if (has_type_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->type_name());
    }

    // optional string default_value = 7;
    if (has_default_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->default_value());
    }

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

    // optional .google.protobuf.FieldOptions options = 8;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

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

    // optional int32 oneof_index = 9;
    if (has_oneof_index()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->oneof_index());
    }

  }
  if (_has_bits_[8 / 32] & 768u) {
    // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    if (has_label()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
    }

    // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      set_extendee(from.extendee());
    }
    if (cached_has_bits & 0x00000004u) {
      set_type_name(from.type_name());
    }
    if (cached_has_bits & 0x00000008u) {
      set_default_value(from.default_value());
    }
    if (cached_has_bits & 0x00000010u) {
      set_json_name(from.json_name());
    }
    if (cached_has_bits & 0x00000020u) {
      mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
    }
    if (cached_has_bits & 0x00000040u) {
      number_ = from.number_;
    }
    if (cached_has_bits & 0x00000080u) {
      oneof_index_ = from.oneof_index_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
  if (cached_has_bits & 768u) {
    if (cached_has_bits & 0x00000100u) {
      label_ = from.label_;
    }
    if (cached_has_bits & 0x00000200u) {
      type_ = from.type_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool FieldDescriptorProto::IsInitialized() const {
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    FieldDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void FieldDescriptorProto::UnsafeArenaSwap(FieldDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) {
  using std::swap;
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  extendee_.Swap(&other->extendee_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  type_name_.Swap(&other->type_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  default_value_.Swap(&other->default_value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  json_name_.Swap(&other->json_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(number_, other->number_);
  swap(oneof_index_, other->oneof_index_);
  swap(label_, other->label_);
  swap(type_, other->type_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void OneofDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_OneofDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::OneofOptions*>(
      ::google::protobuf::OneofOptions::internal_default_instance());
}
void OneofDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::OneofOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int OneofDescriptorProto::kNameFieldNumber;
const int OneofDescriptorProto::kOptionsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

OneofDescriptorProto::OneofDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto)
}
OneofDescriptorProto::OneofDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto)
}
OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::OneofOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
}

void OneofDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  options_ = NULL;
}

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

void OneofDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const OneofDescriptorProto& OneofDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base);
  return *internal_default_instance();
}


void OneofDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool OneofDescriptorProto::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.OneofDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.OneofDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.OneofOptions options = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.OneofDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.OneofDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.OneofDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // optional .google.protobuf.OneofOptions options = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->_internal_options(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.OneofDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional .google.protobuf.OneofOptions options = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->_internal_options(), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 3u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.OneofOptions options = 2;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_options()->::google::protobuf::OneofOptions::MergeFrom(from.options());
    }
  }
}

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

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

bool OneofDescriptorProto::IsInitialized() const {
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void OneofDescriptorProto::Swap(OneofDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    OneofDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void OneofDescriptorProto::UnsafeArenaSwap(OneofDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) {
  using std::swap;
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumDescriptorProto_EnumReservedRange::kStartFieldNumber;
const int EnumDescriptorProto_EnumReservedRange::kEndFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
}
EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
}
EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&start_, &from.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
    reinterpret_cast<char*>(&start_)) + sizeof(end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
}

void EnumDescriptorProto_EnumReservedRange::SharedCtor() {
  ::memset(&start_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&end_) -
      reinterpret_cast<char*>(&start_)) + sizeof(end_));
}

EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  SharedDtor();
}

void EnumDescriptorProto_EnumReservedRange::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto_EnumReservedRange::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base);
  return *internal_default_instance();
}


void EnumDescriptorProto_EnumReservedRange::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    ::memset(&start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&end_) -
        reinterpret_cast<char*>(&start_)) + sizeof(end_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool EnumDescriptorProto_EnumReservedRange::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.EnumDescriptorProto.EnumReservedRange)
  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)) {
      // optional int32 start = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_start();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &start_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 end = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_end();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto.EnumReservedRange)
}

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

  cached_has_bits = _has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 3u) {
    // optional int32 start = 1;
    if (has_start()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->start());
    }

    // optional int32 end = 2;
    if (has_end()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      start_ = from.start_;
    }
    if (cached_has_bits & 0x00000002u) {
      end_ = from.end_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

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

void EnumDescriptorProto_EnumReservedRange::Swap(EnumDescriptorProto_EnumReservedRange* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    EnumDescriptorProto_EnumReservedRange* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void EnumDescriptorProto_EnumReservedRange::UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* other) {
  using std::swap;
  swap(start_, other->start_);
  swap(end_, other->end_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void EnumDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_EnumDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::EnumOptions*>(
      ::google::protobuf::EnumOptions::internal_default_instance());
}
void EnumDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::EnumOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumDescriptorProto::kNameFieldNumber;
const int EnumDescriptorProto::kValueFieldNumber;
const int EnumDescriptorProto::kOptionsFieldNumber;
const int EnumDescriptorProto::kReservedRangeFieldNumber;
const int EnumDescriptorProto::kReservedNameFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EnumDescriptorProto::EnumDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto)
}
EnumDescriptorProto::EnumDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  value_(arena),
  reserved_range_(arena),
  reserved_name_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto)
}
EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      value_(from.value_),
      reserved_range_(from.reserved_range_),
      reserved_name_(from.reserved_name_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::EnumOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
}

void EnumDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  options_ = NULL;
}

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

void EnumDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base);
  return *internal_default_instance();
}


void EnumDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  value_.Clear();
  reserved_range_.Clear();
  reserved_name_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool EnumDescriptorProto::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.EnumDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.EnumDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_value()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.EnumOptions options = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_reserved_range()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated string reserved_name = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_reserved_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->reserved_name(this->reserved_name_size() - 1).data(),
            static_cast<int>(this->reserved_name(this->reserved_name_size() - 1).length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.EnumDescriptorProto.reserved_name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.EnumDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

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

  // optional .google.protobuf.EnumOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->_internal_options(), output);
  }

  // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->reserved_range_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4,
      this->reserved_range(static_cast<int>(i)),
      output);
  }

  // repeated string reserved_name = 5;
  for (int i = 0, n = this->reserved_name_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->reserved_name(i).data(), static_cast<int>(this->reserved_name(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumDescriptorProto.reserved_name");
    ::google::protobuf::internal::WireFormatLite::WriteString(
      5, this->reserved_name(i), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->value_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->value(static_cast<int>(i)), deterministic, target);
  }

  // optional .google.protobuf.EnumOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->_internal_options(), deterministic, target);
  }

  // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->reserved_range_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, this->reserved_range(static_cast<int>(i)), deterministic, target);
  }

  // repeated string reserved_name = 5;
  for (int i = 0, n = this->reserved_name_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->reserved_name(i).data(), static_cast<int>(this->reserved_name(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumDescriptorProto.reserved_name");
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(5, this->reserved_name(i), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  {
    unsigned int count = static_cast<unsigned int>(this->value_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->value(static_cast<int>(i)));
    }
  }

  // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
  {
    unsigned int count = static_cast<unsigned int>(this->reserved_range_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->reserved_range(static_cast<int>(i)));
    }
  }

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

  if (_has_bits_[0 / 32] & 3u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.EnumOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  value_.MergeFrom(from.value_);
  reserved_range_.MergeFrom(from.reserved_range_);
  reserved_name_.MergeFrom(from.reserved_name_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
    }
  }
}

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

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

bool EnumDescriptorProto::IsInitialized() const {
  if (!::google::protobuf::internal::AllAreInitialized(this->value())) return false;
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    EnumDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void EnumDescriptorProto::UnsafeArenaSwap(EnumDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) {
  using std::swap;
  CastToBase(&value_)->InternalSwap(CastToBase(&other->value_));
  CastToBase(&reserved_range_)->InternalSwap(CastToBase(&other->reserved_range_));
  reserved_name_.InternalSwap(CastToBase(&other->reserved_name_));
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void EnumValueDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_EnumValueDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::EnumValueOptions*>(
      ::google::protobuf::EnumValueOptions::internal_default_instance());
}
void EnumValueDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::EnumValueOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumValueDescriptorProto::kNameFieldNumber;
const int EnumValueDescriptorProto::kNumberFieldNumber;
const int EnumValueDescriptorProto::kOptionsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EnumValueDescriptorProto::EnumValueDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto)
}
EnumValueDescriptorProto::EnumValueDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto)
}
EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::EnumValueOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  number_ = from.number_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
}

void EnumValueDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&options_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&number_) -
      reinterpret_cast<char*>(&options_)) + sizeof(number_));
}

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

void EnumValueDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base);
  return *internal_default_instance();
}


void EnumValueDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  number_ = 0;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool EnumValueDescriptorProto::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.EnumValueDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.EnumValueDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 number = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_number();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &number_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.EnumValueOptions options = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumValueDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

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

  // optional .google.protobuf.EnumValueOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->_internal_options(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumValueDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

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

  // optional .google.protobuf.EnumValueOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->_internal_options(), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 7u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.EnumValueOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

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

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
    }
    if (cached_has_bits & 0x00000004u) {
      number_ = from.number_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool EnumValueDescriptorProto::IsInitialized() const {
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    EnumValueDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void EnumValueDescriptorProto::UnsafeArenaSwap(EnumValueDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) {
  using std::swap;
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(number_, other->number_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void ServiceDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_ServiceDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::ServiceOptions*>(
      ::google::protobuf::ServiceOptions::internal_default_instance());
}
void ServiceDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::ServiceOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ServiceDescriptorProto::kNameFieldNumber;
const int ServiceDescriptorProto::kMethodFieldNumber;
const int ServiceDescriptorProto::kOptionsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ServiceDescriptorProto::ServiceDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto)
}
ServiceDescriptorProto::ServiceDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  method_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto)
}
ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      method_(from.method_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::ServiceOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
}

void ServiceDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  options_ = NULL;
}

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

void ServiceDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base);
  return *internal_default_instance();
}


void ServiceDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  method_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool ServiceDescriptorProto::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.ServiceDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.ServiceDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.MethodDescriptorProto method = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_method()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.ServiceOptions options = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.ServiceDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.ServiceDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

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

  // optional .google.protobuf.ServiceOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->_internal_options(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.ServiceDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->method_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->method(static_cast<int>(i)), deterministic, target);
  }

  // optional .google.protobuf.ServiceOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, this->_internal_options(), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  {
    unsigned int count = static_cast<unsigned int>(this->method_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->method(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 3u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.ServiceOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  method_.MergeFrom(from.method_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
    }
  }
}

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

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

bool ServiceDescriptorProto::IsInitialized() const {
  if (!::google::protobuf::internal::AllAreInitialized(this->method())) return false;
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    ServiceDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void ServiceDescriptorProto::UnsafeArenaSwap(ServiceDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) {
  using std::swap;
  CastToBase(&method_)->InternalSwap(CastToBase(&other->method_));
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void MethodDescriptorProto::InitAsDefaultInstance() {
  ::google::protobuf::_MethodDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::MethodOptions*>(
      ::google::protobuf::MethodOptions::internal_default_instance());
}
void MethodDescriptorProto::unsafe_arena_set_allocated_options(
    ::google::protobuf::MethodOptions* options) {
  if (GetArenaNoVirtual() == NULL) {
    delete options_;
  }
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MethodDescriptorProto::kNameFieldNumber;
const int MethodDescriptorProto::kInputTypeFieldNumber;
const int MethodDescriptorProto::kOutputTypeFieldNumber;
const int MethodDescriptorProto::kOptionsFieldNumber;
const int MethodDescriptorProto::kClientStreamingFieldNumber;
const int MethodDescriptorProto::kServerStreamingFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

MethodDescriptorProto::MethodDescriptorProto()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto)
}
MethodDescriptorProto::MethodDescriptorProto(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto)
}
MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name()) {
    name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name(),
      GetArenaNoVirtual());
  }
  input_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_input_type()) {
    input_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.input_type(),
      GetArenaNoVirtual());
  }
  output_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_output_type()) {
    output_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.output_type(),
      GetArenaNoVirtual());
  }
  if (from.has_options()) {
    options_ = new ::google::protobuf::MethodOptions(*from.options_);
  } else {
    options_ = NULL;
  }
  ::memcpy(&client_streaming_, &from.client_streaming_,
    static_cast<size_t>(reinterpret_cast<char*>(&server_streaming_) -
    reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
}

void MethodDescriptorProto::SharedCtor() {
  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  input_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  output_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&options_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&server_streaming_) -
      reinterpret_cast<char*>(&options_)) + sizeof(server_streaming_));
}

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

void MethodDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  input_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  output_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete options_;
}

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

const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base);
  return *internal_default_instance();
}


void MethodDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 15u) {
    if (cached_has_bits & 0x00000001u) {
      name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      input_type_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      output_type_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      GOOGLE_DCHECK(options_ != NULL);
      options_->Clear();
    }
  }
  ::memset(&client_streaming_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&server_streaming_) -
      reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_));
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool MethodDescriptorProto::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.MethodDescriptorProto)
  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)) {
      // optional string name = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name().data(), static_cast<int>(this->name().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.MethodDescriptorProto.name");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string input_type = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_input_type()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->input_type().data(), static_cast<int>(this->input_type().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.MethodDescriptorProto.input_type");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string output_type = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_output_type()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->output_type().data(), static_cast<int>(this->output_type().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.MethodDescriptorProto.output_type");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.MethodOptions options = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_options()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool client_streaming = 5 [default = false];
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_client_streaming();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &client_streaming_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool server_streaming = 6 [default = false];
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
          set_has_server_streaming();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &server_streaming_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.MethodDescriptorProto)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.MethodDescriptorProto)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name(), output);
  }

  // optional string input_type = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->input_type().data(), static_cast<int>(this->input_type().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.input_type");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->input_type(), output);
  }

  // optional string output_type = 3;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->output_type().data(), static_cast<int>(this->output_type().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.output_type");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      3, this->output_type(), output);
  }

  // optional .google.protobuf.MethodOptions options = 4;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, this->_internal_options(), output);
  }

  // optional bool client_streaming = 5 [default = false];
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->client_streaming(), output);
  }

  // optional bool server_streaming = 6 [default = false];
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->server_streaming(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name().data(), static_cast<int>(this->name().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional string input_type = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->input_type().data(), static_cast<int>(this->input_type().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.input_type");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->input_type(), target);
  }

  // optional string output_type = 3;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->output_type().data(), static_cast<int>(this->output_type().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.output_type");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->output_type(), target);
  }

  // optional .google.protobuf.MethodOptions options = 4;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, this->_internal_options(), deterministic, target);
  }

  // optional bool client_streaming = 5 [default = false];
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->client_streaming(), target);
  }

  // optional bool server_streaming = 6 [default = false];
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(6, this->server_streaming(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (_has_bits_[0 / 32] & 63u) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional string input_type = 2;
    if (has_input_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->input_type());
    }

    // optional string output_type = 3;
    if (has_output_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->output_type());
    }

    // optional .google.protobuf.MethodOptions options = 4;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *options_);
    }

    // optional bool client_streaming = 5 [default = false];
    if (has_client_streaming()) {
      total_size += 1 + 1;
    }

    // optional bool server_streaming = 6 [default = false];
    if (has_server_streaming()) {
      total_size += 1 + 1;
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 63u) {
    if (cached_has_bits & 0x00000001u) {
      set_name(from.name());
    }
    if (cached_has_bits & 0x00000002u) {
      set_input_type(from.input_type());
    }
    if (cached_has_bits & 0x00000004u) {
      set_output_type(from.output_type());
    }
    if (cached_has_bits & 0x00000008u) {
      mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
    }
    if (cached_has_bits & 0x00000010u) {
      client_streaming_ = from.client_streaming_;
    }
    if (cached_has_bits & 0x00000020u) {
      server_streaming_ = from.server_streaming_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool MethodDescriptorProto::IsInitialized() const {
  if (has_options()) {
    if (!this->options_->IsInitialized()) return false;
  }
  return true;
}

void MethodDescriptorProto::Swap(MethodDescriptorProto* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    MethodDescriptorProto* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void MethodDescriptorProto::UnsafeArenaSwap(MethodDescriptorProto* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) {
  using std::swap;
  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  input_type_.Swap(&other->input_type_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  output_type_.Swap(&other->output_type_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(options_, other->options_);
  swap(client_streaming_, other->client_streaming_);
  swap(server_streaming_, other->server_streaming_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void FileOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FileOptions::kJavaPackageFieldNumber;
const int FileOptions::kJavaOuterClassnameFieldNumber;
const int FileOptions::kJavaMultipleFilesFieldNumber;
const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
const int FileOptions::kJavaStringCheckUtf8FieldNumber;
const int FileOptions::kOptimizeForFieldNumber;
const int FileOptions::kGoPackageFieldNumber;
const int FileOptions::kCcGenericServicesFieldNumber;
const int FileOptions::kJavaGenericServicesFieldNumber;
const int FileOptions::kPyGenericServicesFieldNumber;
const int FileOptions::kPhpGenericServicesFieldNumber;
const int FileOptions::kDeprecatedFieldNumber;
const int FileOptions::kCcEnableArenasFieldNumber;
const int FileOptions::kObjcClassPrefixFieldNumber;
const int FileOptions::kCsharpNamespaceFieldNumber;
const int FileOptions::kSwiftPrefixFieldNumber;
const int FileOptions::kPhpClassPrefixFieldNumber;
const int FileOptions::kPhpNamespaceFieldNumber;
const int FileOptions::kPhpMetadataNamespaceFieldNumber;
const int FileOptions::kRubyPackageFieldNumber;
const int FileOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

FileOptions::FileOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.FileOptions)
}
FileOptions::FileOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions)
}
FileOptions::FileOptions(const FileOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  java_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_java_package()) {
    java_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.java_package(),
      GetArenaNoVirtual());
  }
  java_outer_classname_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_java_outer_classname()) {
    java_outer_classname_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.java_outer_classname(),
      GetArenaNoVirtual());
  }
  go_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_go_package()) {
    go_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.go_package(),
      GetArenaNoVirtual());
  }
  objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_objc_class_prefix()) {
    objc_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix(),
      GetArenaNoVirtual());
  }
  csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_csharp_namespace()) {
    csharp_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace(),
      GetArenaNoVirtual());
  }
  swift_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_swift_prefix()) {
    swift_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.swift_prefix(),
      GetArenaNoVirtual());
  }
  php_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_php_class_prefix()) {
    php_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix(),
      GetArenaNoVirtual());
  }
  php_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_php_namespace()) {
    php_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_namespace(),
      GetArenaNoVirtual());
  }
  php_metadata_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_php_metadata_namespace()) {
    php_metadata_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_metadata_namespace(),
      GetArenaNoVirtual());
  }
  ruby_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_ruby_package()) {
    ruby_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.ruby_package(),
      GetArenaNoVirtual());
  }
  ::memcpy(&java_multiple_files_, &from.java_multiple_files_,
    static_cast<size_t>(reinterpret_cast<char*>(&optimize_for_) -
    reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(optimize_for_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
}

void FileOptions::SharedCtor() {
  java_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  java_outer_classname_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  go_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  swift_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  php_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  php_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  php_metadata_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ruby_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&java_multiple_files_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&cc_enable_arenas_) -
      reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(cc_enable_arenas_));
  optimize_for_ = 1;
}

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

void FileOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  java_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  java_outer_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  go_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  csharp_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  swift_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  php_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  php_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  php_metadata_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ruby_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

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

const FileOptions& FileOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base);
  return *internal_default_instance();
}


void FileOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      java_package_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      java_outer_classname_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      go_package_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      objc_class_prefix_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000010u) {
      csharp_namespace_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000020u) {
      swift_prefix_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000040u) {
      php_class_prefix_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000080u) {
      php_namespace_.ClearNonDefaultToEmpty();
    }
  }
  if (cached_has_bits & 768u) {
    if (cached_has_bits & 0x00000100u) {
      php_metadata_namespace_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000200u) {
      ruby_package_.ClearNonDefaultToEmpty();
    }
  }
  if (cached_has_bits & 64512u) {
    ::memset(&java_multiple_files_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&py_generic_services_) -
        reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(py_generic_services_));
  }
  if (cached_has_bits & 983040u) {
    ::memset(&php_generic_services_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&cc_enable_arenas_) -
        reinterpret_cast<char*>(&php_generic_services_)) + sizeof(cc_enable_arenas_));
    optimize_for_ = 1;
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool FileOptions::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.FileOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string java_package = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_java_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->java_package().data(), static_cast<int>(this->java_package().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.java_package");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string java_outer_classname = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_java_outer_classname()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->java_outer_classname().data(), static_cast<int>(this->java_outer_classname().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.java_outer_classname");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
            set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                9, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool java_multiple_files = 10 [default = false];
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
          set_has_java_multiple_files();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_multiple_files_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string go_package = 11;
      case 11: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_go_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->go_package().data(), static_cast<int>(this->go_package().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.go_package");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool cc_generic_services = 16 [default = false];
      case 16: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(128u /* 128 & 0xFF */)) {
          set_has_cc_generic_services();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &cc_generic_services_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool java_generic_services = 17 [default = false];
      case 17: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(136u /* 136 & 0xFF */)) {
          set_has_java_generic_services();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_generic_services_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool py_generic_services = 18 [default = false];
      case 18: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(144u /* 144 & 0xFF */)) {
          set_has_py_generic_services();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &py_generic_services_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
      case 20: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(160u /* 160 & 0xFF */)) {
          set_has_java_generate_equals_and_hash();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_generate_equals_and_hash_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool deprecated = 23 [default = false];
      case 23: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(184u /* 184 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool java_string_check_utf8 = 27 [default = false];
      case 27: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(216u /* 216 & 0xFF */)) {
          set_has_java_string_check_utf8();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_string_check_utf8_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool cc_enable_arenas = 31 [default = false];
      case 31: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(248u /* 248 & 0xFF */)) {
          set_has_cc_enable_arenas();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &cc_enable_arenas_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string objc_class_prefix = 36;
      case 36: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 290 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_objc_class_prefix()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->objc_class_prefix().data(), static_cast<int>(this->objc_class_prefix().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.objc_class_prefix");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string csharp_namespace = 37;
      case 37: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(42u /* 298 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_csharp_namespace()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->csharp_namespace().data(), static_cast<int>(this->csharp_namespace().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.csharp_namespace");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string swift_prefix = 39;
      case 39: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 314 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_swift_prefix()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->swift_prefix().data(), static_cast<int>(this->swift_prefix().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.swift_prefix");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string php_class_prefix = 40;
      case 40: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 322 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_php_class_prefix()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->php_class_prefix().data(), static_cast<int>(this->php_class_prefix().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.php_class_prefix");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string php_namespace = 41;
      case 41: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(74u /* 330 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_php_namespace()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->php_namespace().data(), static_cast<int>(this->php_namespace().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.php_namespace");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool php_generic_services = 42 [default = false];
      case 42: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(80u /* 336 & 0xFF */)) {
          set_has_php_generic_services();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &php_generic_services_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string php_metadata_namespace = 44;
      case 44: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(98u /* 354 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_php_metadata_namespace()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->php_metadata_namespace().data(), static_cast<int>(this->php_metadata_namespace().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.php_metadata_namespace");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string ruby_package = 45;
      case 45: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(106u /* 362 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_ruby_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->ruby_package().data(), static_cast<int>(this->ruby_package().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.FileOptions.ruby_package");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.FileOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.FileOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional string java_package = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->java_package().data(), static_cast<int>(this->java_package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.java_package");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->java_package(), output);
  }

  // optional string java_outer_classname = 8;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->java_outer_classname().data(), static_cast<int>(this->java_outer_classname().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.java_outer_classname");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      8, this->java_outer_classname(), output);
  }

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  if (cached_has_bits & 0x00080000u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      9, this->optimize_for(), output);
  }

  // optional bool java_multiple_files = 10 [default = false];
  if (cached_has_bits & 0x00000400u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
  }

  // optional string go_package = 11;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->go_package().data(), static_cast<int>(this->go_package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.go_package");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      11, this->go_package(), output);
  }

  // optional bool cc_generic_services = 16 [default = false];
  if (cached_has_bits & 0x00002000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
  }

  // optional bool java_generic_services = 17 [default = false];
  if (cached_has_bits & 0x00004000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
  }

  // optional bool py_generic_services = 18 [default = false];
  if (cached_has_bits & 0x00008000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
  }

  // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
  if (cached_has_bits & 0x00000800u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
  }

  // optional bool deprecated = 23 [default = false];
  if (cached_has_bits & 0x00020000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output);
  }

  // optional bool java_string_check_utf8 = 27 [default = false];
  if (cached_has_bits & 0x00001000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output);
  }

  // optional bool cc_enable_arenas = 31 [default = false];
  if (cached_has_bits & 0x00040000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(31, this->cc_enable_arenas(), output);
  }

  // optional string objc_class_prefix = 36;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->objc_class_prefix().data(), static_cast<int>(this->objc_class_prefix().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.objc_class_prefix");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      36, this->objc_class_prefix(), output);
  }

  // optional string csharp_namespace = 37;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->csharp_namespace().data(), static_cast<int>(this->csharp_namespace().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.csharp_namespace");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      37, this->csharp_namespace(), output);
  }

  // optional string swift_prefix = 39;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->swift_prefix().data(), static_cast<int>(this->swift_prefix().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.swift_prefix");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      39, this->swift_prefix(), output);
  }

  // optional string php_class_prefix = 40;
  if (cached_has_bits & 0x00000040u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->php_class_prefix().data(), static_cast<int>(this->php_class_prefix().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_class_prefix");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      40, this->php_class_prefix(), output);
  }

  // optional string php_namespace = 41;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->php_namespace().data(), static_cast<int>(this->php_namespace().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_namespace");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      41, this->php_namespace(), output);
  }

  // optional bool php_generic_services = 42 [default = false];
  if (cached_has_bits & 0x00010000u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(42, this->php_generic_services(), output);
  }

  // optional string php_metadata_namespace = 44;
  if (cached_has_bits & 0x00000100u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->php_metadata_namespace().data(), static_cast<int>(this->php_metadata_namespace().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_metadata_namespace");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      44, this->php_metadata_namespace(), output);
  }

  // optional string ruby_package = 45;
  if (cached_has_bits & 0x00000200u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->ruby_package().data(), static_cast<int>(this->ruby_package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.ruby_package");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      45, this->ruby_package(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional string java_package = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->java_package().data(), static_cast<int>(this->java_package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.java_package");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->java_package(), target);
  }

  // optional string java_outer_classname = 8;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->java_outer_classname().data(), static_cast<int>(this->java_outer_classname().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.java_outer_classname");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        8, this->java_outer_classname(), target);
  }

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  if (cached_has_bits & 0x00080000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      9, this->optimize_for(), target);
  }

  // optional bool java_multiple_files = 10 [default = false];
  if (cached_has_bits & 0x00000400u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
  }

  // optional string go_package = 11;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->go_package().data(), static_cast<int>(this->go_package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.go_package");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        11, this->go_package(), target);
  }

  // optional bool cc_generic_services = 16 [default = false];
  if (cached_has_bits & 0x00002000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
  }

  // optional bool java_generic_services = 17 [default = false];
  if (cached_has_bits & 0x00004000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
  }

  // optional bool py_generic_services = 18 [default = false];
  if (cached_has_bits & 0x00008000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
  }

  // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
  if (cached_has_bits & 0x00000800u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
  }

  // optional bool deprecated = 23 [default = false];
  if (cached_has_bits & 0x00020000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target);
  }

  // optional bool java_string_check_utf8 = 27 [default = false];
  if (cached_has_bits & 0x00001000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target);
  }

  // optional bool cc_enable_arenas = 31 [default = false];
  if (cached_has_bits & 0x00040000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(31, this->cc_enable_arenas(), target);
  }

  // optional string objc_class_prefix = 36;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->objc_class_prefix().data(), static_cast<int>(this->objc_class_prefix().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.objc_class_prefix");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        36, this->objc_class_prefix(), target);
  }

  // optional string csharp_namespace = 37;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->csharp_namespace().data(), static_cast<int>(this->csharp_namespace().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.csharp_namespace");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        37, this->csharp_namespace(), target);
  }

  // optional string swift_prefix = 39;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->swift_prefix().data(), static_cast<int>(this->swift_prefix().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.swift_prefix");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        39, this->swift_prefix(), target);
  }

  // optional string php_class_prefix = 40;
  if (cached_has_bits & 0x00000040u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->php_class_prefix().data(), static_cast<int>(this->php_class_prefix().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_class_prefix");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        40, this->php_class_prefix(), target);
  }

  // optional string php_namespace = 41;
  if (cached_has_bits & 0x00000080u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->php_namespace().data(), static_cast<int>(this->php_namespace().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_namespace");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        41, this->php_namespace(), target);
  }

  // optional bool php_generic_services = 42 [default = false];
  if (cached_has_bits & 0x00010000u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(42, this->php_generic_services(), target);
  }

  // optional string php_metadata_namespace = 44;
  if (cached_has_bits & 0x00000100u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->php_metadata_namespace().data(), static_cast<int>(this->php_metadata_namespace().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_metadata_namespace");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        44, this->php_metadata_namespace(), target);
  }

  // optional string ruby_package = 45;
  if (cached_has_bits & 0x00000200u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->ruby_package().data(), static_cast<int>(this->ruby_package().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.ruby_package");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        45, this->ruby_package(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 255u) {
    // optional string java_package = 1;
    if (has_java_package()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->java_package());
    }

    // optional string java_outer_classname = 8;
    if (has_java_outer_classname()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->java_outer_classname());
    }

    // optional string go_package = 11;
    if (has_go_package()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->go_package());
    }

    // optional string objc_class_prefix = 36;
    if (has_objc_class_prefix()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->objc_class_prefix());
    }

    // optional string csharp_namespace = 37;
    if (has_csharp_namespace()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->csharp_namespace());
    }

    // optional string swift_prefix = 39;
    if (has_swift_prefix()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->swift_prefix());
    }

    // optional string php_class_prefix = 40;
    if (has_php_class_prefix()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->php_class_prefix());
    }

    // optional string php_namespace = 41;
    if (has_php_namespace()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->php_namespace());
    }

  }
  if (_has_bits_[8 / 32] & 65280u) {
    // optional string php_metadata_namespace = 44;
    if (has_php_metadata_namespace()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->php_metadata_namespace());
    }

    // optional string ruby_package = 45;
    if (has_ruby_package()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->ruby_package());
    }

    // optional bool java_multiple_files = 10 [default = false];
    if (has_java_multiple_files()) {
      total_size += 1 + 1;
    }

    // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
    if (has_java_generate_equals_and_hash()) {
      total_size += 2 + 1;
    }

    // optional bool java_string_check_utf8 = 27 [default = false];
    if (has_java_string_check_utf8()) {
      total_size += 2 + 1;
    }

    // optional bool cc_generic_services = 16 [default = false];
    if (has_cc_generic_services()) {
      total_size += 2 + 1;
    }

    // optional bool java_generic_services = 17 [default = false];
    if (has_java_generic_services()) {
      total_size += 2 + 1;
    }

    // optional bool py_generic_services = 18 [default = false];
    if (has_py_generic_services()) {
      total_size += 2 + 1;
    }

  }
  if (_has_bits_[16 / 32] & 983040u) {
    // optional bool php_generic_services = 42 [default = false];
    if (has_php_generic_services()) {
      total_size += 2 + 1;
    }

    // optional bool deprecated = 23 [default = false];
    if (has_deprecated()) {
      total_size += 2 + 1;
    }

    // optional bool cc_enable_arenas = 31 [default = false];
    if (has_cc_enable_arenas()) {
      total_size += 2 + 1;
    }

    // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    if (has_optimize_for()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 255u) {
    if (cached_has_bits & 0x00000001u) {
      set_java_package(from.java_package());
    }
    if (cached_has_bits & 0x00000002u) {
      set_java_outer_classname(from.java_outer_classname());
    }
    if (cached_has_bits & 0x00000004u) {
      set_go_package(from.go_package());
    }
    if (cached_has_bits & 0x00000008u) {
      set_objc_class_prefix(from.objc_class_prefix());
    }
    if (cached_has_bits & 0x00000010u) {
      set_csharp_namespace(from.csharp_namespace());
    }
    if (cached_has_bits & 0x00000020u) {
      set_swift_prefix(from.swift_prefix());
    }
    if (cached_has_bits & 0x00000040u) {
      set_php_class_prefix(from.php_class_prefix());
    }
    if (cached_has_bits & 0x00000080u) {
      set_php_namespace(from.php_namespace());
    }
  }
  if (cached_has_bits & 65280u) {
    if (cached_has_bits & 0x00000100u) {
      set_php_metadata_namespace(from.php_metadata_namespace());
    }
    if (cached_has_bits & 0x00000200u) {
      set_ruby_package(from.ruby_package());
    }
    if (cached_has_bits & 0x00000400u) {
      java_multiple_files_ = from.java_multiple_files_;
    }
    if (cached_has_bits & 0x00000800u) {
      java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_;
    }
    if (cached_has_bits & 0x00001000u) {
      java_string_check_utf8_ = from.java_string_check_utf8_;
    }
    if (cached_has_bits & 0x00002000u) {
      cc_generic_services_ = from.cc_generic_services_;
    }
    if (cached_has_bits & 0x00004000u) {
      java_generic_services_ = from.java_generic_services_;
    }
    if (cached_has_bits & 0x00008000u) {
      py_generic_services_ = from.py_generic_services_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
  if (cached_has_bits & 983040u) {
    if (cached_has_bits & 0x00010000u) {
      php_generic_services_ = from.php_generic_services_;
    }
    if (cached_has_bits & 0x00020000u) {
      deprecated_ = from.deprecated_;
    }
    if (cached_has_bits & 0x00040000u) {
      cc_enable_arenas_ = from.cc_enable_arenas_;
    }
    if (cached_has_bits & 0x00080000u) {
      optimize_for_ = from.optimize_for_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool FileOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void FileOptions::Swap(FileOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    FileOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void FileOptions::UnsafeArenaSwap(FileOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void FileOptions::InternalSwap(FileOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  java_package_.Swap(&other->java_package_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  java_outer_classname_.Swap(&other->java_outer_classname_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  go_package_.Swap(&other->go_package_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  objc_class_prefix_.Swap(&other->objc_class_prefix_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  csharp_namespace_.Swap(&other->csharp_namespace_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swift_prefix_.Swap(&other->swift_prefix_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  php_class_prefix_.Swap(&other->php_class_prefix_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  php_namespace_.Swap(&other->php_namespace_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  php_metadata_namespace_.Swap(&other->php_metadata_namespace_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  ruby_package_.Swap(&other->ruby_package_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(java_multiple_files_, other->java_multiple_files_);
  swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
  swap(java_string_check_utf8_, other->java_string_check_utf8_);
  swap(cc_generic_services_, other->cc_generic_services_);
  swap(java_generic_services_, other->java_generic_services_);
  swap(py_generic_services_, other->py_generic_services_);
  swap(php_generic_services_, other->php_generic_services_);
  swap(deprecated_, other->deprecated_);
  swap(cc_enable_arenas_, other->cc_enable_arenas_);
  swap(optimize_for_, other->optimize_for_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void MessageOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MessageOptions::kMessageSetWireFormatFieldNumber;
const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
const int MessageOptions::kDeprecatedFieldNumber;
const int MessageOptions::kMapEntryFieldNumber;
const int MessageOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

MessageOptions::MessageOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions)
}
MessageOptions::MessageOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions)
}
MessageOptions::MessageOptions(const MessageOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  ::memcpy(&message_set_wire_format_, &from.message_set_wire_format_,
    static_cast<size_t>(reinterpret_cast<char*>(&map_entry_) -
    reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
}

void MessageOptions::SharedCtor() {
  ::memset(&message_set_wire_format_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&map_entry_) -
      reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
}

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

void MessageOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const MessageOptions& MessageOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base);
  return *internal_default_instance();
}


void MessageOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  ::memset(&message_set_wire_format_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&map_entry_) -
      reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool MessageOptions::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.MessageOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool message_set_wire_format = 1 [default = false];
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_message_set_wire_format();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &message_set_wire_format_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool no_standard_descriptor_accessor = 2 [default = false];
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_no_standard_descriptor_accessor();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &no_standard_descriptor_accessor_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool deprecated = 3 [default = false];
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool map_entry = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
          set_has_map_entry();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &map_entry_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.MessageOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.MessageOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool message_set_wire_format = 1 [default = false];
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
  }

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
  }

  // optional bool map_entry = 7;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->map_entry(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool message_set_wire_format = 1 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
  }

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
  }

  // optional bool map_entry = 7;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->map_entry(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 15u) {
    // optional bool message_set_wire_format = 1 [default = false];
    if (has_message_set_wire_format()) {
      total_size += 1 + 1;
    }

    // optional bool no_standard_descriptor_accessor = 2 [default = false];
    if (has_no_standard_descriptor_accessor()) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (has_deprecated()) {
      total_size += 1 + 1;
    }

    // optional bool map_entry = 7;
    if (has_map_entry()) {
      total_size += 1 + 1;
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 15u) {
    if (cached_has_bits & 0x00000001u) {
      message_set_wire_format_ = from.message_set_wire_format_;
    }
    if (cached_has_bits & 0x00000002u) {
      no_standard_descriptor_accessor_ = from.no_standard_descriptor_accessor_;
    }
    if (cached_has_bits & 0x00000004u) {
      deprecated_ = from.deprecated_;
    }
    if (cached_has_bits & 0x00000008u) {
      map_entry_ = from.map_entry_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool MessageOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void MessageOptions::Swap(MessageOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    MessageOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void MessageOptions::UnsafeArenaSwap(MessageOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void MessageOptions::InternalSwap(MessageOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(message_set_wire_format_, other->message_set_wire_format_);
  swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
  swap(deprecated_, other->deprecated_);
  swap(map_entry_, other->map_entry_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void FieldOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FieldOptions::kCtypeFieldNumber;
const int FieldOptions::kPackedFieldNumber;
const int FieldOptions::kJstypeFieldNumber;
const int FieldOptions::kLazyFieldNumber;
const int FieldOptions::kDeprecatedFieldNumber;
const int FieldOptions::kWeakFieldNumber;
const int FieldOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

FieldOptions::FieldOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions)
}
FieldOptions::FieldOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions)
}
FieldOptions::FieldOptions(const FieldOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  ::memcpy(&ctype_, &from.ctype_,
    static_cast<size_t>(reinterpret_cast<char*>(&jstype_) -
    reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
}

void FieldOptions::SharedCtor() {
  ::memset(&ctype_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&jstype_) -
      reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
}

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

void FieldOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const FieldOptions& FieldOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base);
  return *internal_default_instance();
}


void FieldOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 63u) {
    ::memset(&ctype_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&jstype_) -
        reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool FieldOptions::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.FieldOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
            set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                1, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool packed = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_packed();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &packed_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool deprecated = 3 [default = false];
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool lazy = 5 [default = false];
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_lazy();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &lazy_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldOptions_JSType_IsValid(value)) {
            set_jstype(static_cast< ::google::protobuf::FieldOptions_JSType >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                6, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool weak = 10 [default = false];
      case 10: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
          set_has_weak();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &weak_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.FieldOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.FieldOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->ctype(), output);
  }

  // optional bool packed = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
  }

  // optional bool lazy = 5 [default = false];
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output);
  }

  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      6, this->jstype(), output);
  }

  // optional bool weak = 10 [default = false];
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->ctype(), target);
  }

  // optional bool packed = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
  }

  // optional bool lazy = 5 [default = false];
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target);
  }

  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      6, this->jstype(), target);
  }

  // optional bool weak = 10 [default = false];
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 63u) {
    // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    if (has_ctype()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
    }

    // optional bool packed = 2;
    if (has_packed()) {
      total_size += 1 + 1;
    }

    // optional bool lazy = 5 [default = false];
    if (has_lazy()) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (has_deprecated()) {
      total_size += 1 + 1;
    }

    // optional bool weak = 10 [default = false];
    if (has_weak()) {
      total_size += 1 + 1;
    }

    // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
    if (has_jstype()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 63u) {
    if (cached_has_bits & 0x00000001u) {
      ctype_ = from.ctype_;
    }
    if (cached_has_bits & 0x00000002u) {
      packed_ = from.packed_;
    }
    if (cached_has_bits & 0x00000004u) {
      lazy_ = from.lazy_;
    }
    if (cached_has_bits & 0x00000008u) {
      deprecated_ = from.deprecated_;
    }
    if (cached_has_bits & 0x00000010u) {
      weak_ = from.weak_;
    }
    if (cached_has_bits & 0x00000020u) {
      jstype_ = from.jstype_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool FieldOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void FieldOptions::Swap(FieldOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    FieldOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void FieldOptions::UnsafeArenaSwap(FieldOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void FieldOptions::InternalSwap(FieldOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(ctype_, other->ctype_);
  swap(packed_, other->packed_);
  swap(lazy_, other->lazy_);
  swap(deprecated_, other->deprecated_);
  swap(weak_, other->weak_);
  swap(jstype_, other->jstype_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void OneofOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int OneofOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

OneofOptions::OneofOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.OneofOptions)
}
OneofOptions::OneofOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions)
}
OneofOptions::OneofOptions(const OneofOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
}

void OneofOptions::SharedCtor() {
}

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

void OneofOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const OneofOptions& OneofOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base);
  return *internal_default_instance();
}


void OneofOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool OneofOptions::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.OneofOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.OneofOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.OneofOptions)
  return false;
#undef DO_
}

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

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.OneofOptions)
}

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

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
}

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

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

bool OneofOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void OneofOptions::Swap(OneofOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    OneofOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void OneofOptions::UnsafeArenaSwap(OneofOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void OneofOptions::InternalSwap(OneofOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void EnumOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumOptions::kAllowAliasFieldNumber;
const int EnumOptions::kDeprecatedFieldNumber;
const int EnumOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EnumOptions::EnumOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions)
}
EnumOptions::EnumOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions)
}
EnumOptions::EnumOptions(const EnumOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  ::memcpy(&allow_alias_, &from.allow_alias_,
    static_cast<size_t>(reinterpret_cast<char*>(&deprecated_) -
    reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
}

void EnumOptions::SharedCtor() {
  ::memset(&allow_alias_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&deprecated_) -
      reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
}

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

void EnumOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const EnumOptions& EnumOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base);
  return *internal_default_instance();
}


void EnumOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  ::memset(&allow_alias_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&deprecated_) -
      reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool EnumOptions::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.EnumOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool allow_alias = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_allow_alias();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &allow_alias_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bool deprecated = 3 [default = false];
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.EnumOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool allow_alias = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool allow_alias = 2;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 3u) {
    // optional bool allow_alias = 2;
    if (has_allow_alias()) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (has_deprecated()) {
      total_size += 1 + 1;
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      allow_alias_ = from.allow_alias_;
    }
    if (cached_has_bits & 0x00000002u) {
      deprecated_ = from.deprecated_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool EnumOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void EnumOptions::Swap(EnumOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    EnumOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void EnumOptions::UnsafeArenaSwap(EnumOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void EnumOptions::InternalSwap(EnumOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(allow_alias_, other->allow_alias_);
  swap(deprecated_, other->deprecated_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void EnumValueOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumValueOptions::kDeprecatedFieldNumber;
const int EnumValueOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EnumValueOptions::EnumValueOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions)
}
EnumValueOptions::EnumValueOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions)
}
EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  deprecated_ = from.deprecated_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
}

void EnumValueOptions::SharedCtor() {
  deprecated_ = false;
}

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

void EnumValueOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const EnumValueOptions& EnumValueOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base);
  return *internal_default_instance();
}


void EnumValueOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  deprecated_ = false;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool EnumValueOptions::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.EnumValueOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool deprecated = 1 [default = false];
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool deprecated = 1 [default = false];
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->deprecated(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool deprecated = 1 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->deprecated(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  // optional bool deprecated = 1 [default = false];
  if (has_deprecated()) {
    total_size += 1 + 1;
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  if (from.has_deprecated()) {
    set_deprecated(from.deprecated());
  }
}

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

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

bool EnumValueOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void EnumValueOptions::Swap(EnumValueOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    EnumValueOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void EnumValueOptions::UnsafeArenaSwap(EnumValueOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void EnumValueOptions::InternalSwap(EnumValueOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(deprecated_, other->deprecated_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void ServiceOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ServiceOptions::kDeprecatedFieldNumber;
const int ServiceOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ServiceOptions::ServiceOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions)
}
ServiceOptions::ServiceOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions)
}
ServiceOptions::ServiceOptions(const ServiceOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  deprecated_ = from.deprecated_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
}

void ServiceOptions::SharedCtor() {
  deprecated_ = false;
}

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

void ServiceOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const ServiceOptions& ServiceOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base);
  return *internal_default_instance();
}


void ServiceOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  deprecated_ = false;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool ServiceOptions::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.ServiceOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool deprecated = 33 [default = false];
      case 33: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 264 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.ServiceOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool deprecated = 33 [default = false];
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool deprecated = 33 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  // optional bool deprecated = 33 [default = false];
  if (has_deprecated()) {
    total_size += 2 + 1;
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  if (from.has_deprecated()) {
    set_deprecated(from.deprecated());
  }
}

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

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

bool ServiceOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void ServiceOptions::Swap(ServiceOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    ServiceOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void ServiceOptions::UnsafeArenaSwap(ServiceOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void ServiceOptions::InternalSwap(ServiceOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(deprecated_, other->deprecated_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void MethodOptions::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int MethodOptions::kDeprecatedFieldNumber;
const int MethodOptions::kIdempotencyLevelFieldNumber;
const int MethodOptions::kUninterpretedOptionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

MethodOptions::MethodOptions()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions)
}
MethodOptions::MethodOptions(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _extensions_(arena),
  _internal_metadata_(arena),
  uninterpreted_option_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions)
}
MethodOptions::MethodOptions(const MethodOptions& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      uninterpreted_option_(from.uninterpreted_option_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  _extensions_.MergeFrom(from._extensions_);
  ::memcpy(&deprecated_, &from.deprecated_,
    static_cast<size_t>(reinterpret_cast<char*>(&idempotency_level_) -
    reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
}

void MethodOptions::SharedCtor() {
  ::memset(&deprecated_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&idempotency_level_) -
      reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
}

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

void MethodOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const MethodOptions& MethodOptions::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base);
  return *internal_default_instance();
}


void MethodOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _extensions_.Clear();
  uninterpreted_option_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    ::memset(&deprecated_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&idempotency_level_) -
        reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool MethodOptions::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.MethodOptions)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool deprecated = 33 [default = false];
      case 33: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 264 & 0xFF */)) {
          set_has_deprecated();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
      case 34: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 272 & 0xFF */)) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(value)) {
            set_idempotency_level(static_cast< ::google::protobuf::MethodOptions_IdempotencyLevel >(value));
          } else {
            mutable_unknown_fields()->AddVarint(
                34, static_cast< ::google::protobuf::uint64>(value));
          }
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_uninterpreted_option()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input,
              internal_default_instance(),
              _internal_metadata_.mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.MethodOptions)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.MethodOptions)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool deprecated = 33 [default = false];
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
  }

  // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      34, this->idempotency_level(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999,
      this->uninterpreted_option(static_cast<int>(i)),
      output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions)
}

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

  cached_has_bits = _has_bits_[0];
  // optional bool deprecated = 33 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
  }

  // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      34, this->idempotency_level(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.InternalSerializeWithCachedSizesToArray(
      1000, 536870912, deterministic, target);

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions)
  return target;
}

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

  total_size += _extensions_.ByteSize();

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  {
    unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
    total_size += 2UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->uninterpreted_option(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 3u) {
    // optional bool deprecated = 33 [default = false];
    if (has_deprecated()) {
      total_size += 2 + 1;
    }

    // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
    if (has_idempotency_level()) {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->idempotency_level());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      deprecated_ = from.deprecated_;
    }
    if (cached_has_bits & 0x00000002u) {
      idempotency_level_ = from.idempotency_level_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool MethodOptions::IsInitialized() const {
  if (!_extensions_.IsInitialized()) {
    return false;
  }

  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
  return true;
}

void MethodOptions::Swap(MethodOptions* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    MethodOptions* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void MethodOptions::UnsafeArenaSwap(MethodOptions* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void MethodOptions::InternalSwap(MethodOptions* other) {
  using std::swap;
  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
  swap(deprecated_, other->deprecated_);
  swap(idempotency_level_, other->idempotency_level_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
  _extensions_.Swap(&other->_extensions_);
}

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


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

void UninterpretedOption_NamePart::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int UninterpretedOption_NamePart::kNamePartFieldNumber;
const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

UninterpretedOption_NamePart::UninterpretedOption_NamePart()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart)
}
UninterpretedOption_NamePart::UninterpretedOption_NamePart(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart)
}
UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  name_part_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_name_part()) {
    name_part_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_part(),
      GetArenaNoVirtual());
  }
  is_extension_ = from.is_extension_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
}

void UninterpretedOption_NamePart::SharedCtor() {
  name_part_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  is_extension_ = false;
}

UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
  SharedDtor();
}

void UninterpretedOption_NamePart::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  name_part_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

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

const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base);
  return *internal_default_instance();
}


void UninterpretedOption_NamePart::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    name_part_.ClearNonDefaultToEmpty();
  }
  is_extension_ = false;
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool UninterpretedOption_NamePart::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.UninterpretedOption.NamePart)
  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)) {
      // required string name_part = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name_part()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->name_part().data(), static_cast<int>(this->name_part().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.UninterpretedOption.NamePart.name_part");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // required bool is_extension = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          set_has_is_extension();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &is_extension_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption.NamePart)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption.NamePart)
  return false;
#undef DO_
}

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

  cached_has_bits = _has_bits_[0];
  // required string name_part = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name_part().data(), static_cast<int>(this->name_part().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.NamePart.name_part");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->name_part(), output);
  }

  // required bool is_extension = 2;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart)
}

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

  cached_has_bits = _has_bits_[0];
  // required string name_part = 1;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->name_part().data(), static_cast<int>(this->name_part().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.NamePart.name_part");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name_part(), target);
  }

  // required bool is_extension = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart)
  return target;
}

size_t UninterpretedOption_NamePart::RequiredFieldsByteSizeFallback() const {
// @@protoc_insertion_point(required_fields_byte_size_fallback_start:google.protobuf.UninterpretedOption.NamePart)
  size_t total_size = 0;

  if (has_name_part()) {
    // required string name_part = 1;
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name_part());
  }

  if (has_is_extension()) {
    // required bool is_extension = 2;
    total_size += 1 + 1;
  }

  return total_size;
}
size_t UninterpretedOption_NamePart::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption.NamePart)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) {  // All required fields are present.
    // required string name_part = 1;
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->name_part());

    // required bool is_extension = 2;
    total_size += 1 + 1;

  } else {
    total_size += RequiredFieldsByteSizeFallback();
  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      set_name_part(from.name_part());
    }
    if (cached_has_bits & 0x00000002u) {
      is_extension_ = from.is_extension_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool UninterpretedOption_NamePart::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
  return true;
}

void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    UninterpretedOption_NamePart* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void UninterpretedOption_NamePart::UnsafeArenaSwap(UninterpretedOption_NamePart* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) {
  using std::swap;
  name_part_.Swap(&other->name_part_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(is_extension_, other->is_extension_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void UninterpretedOption::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int UninterpretedOption::kNameFieldNumber;
const int UninterpretedOption::kIdentifierValueFieldNumber;
const int UninterpretedOption::kPositiveIntValueFieldNumber;
const int UninterpretedOption::kNegativeIntValueFieldNumber;
const int UninterpretedOption::kDoubleValueFieldNumber;
const int UninterpretedOption::kStringValueFieldNumber;
const int UninterpretedOption::kAggregateValueFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

UninterpretedOption::UninterpretedOption()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption)
}
UninterpretedOption::UninterpretedOption(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  name_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption)
}
UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      name_(from.name_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  identifier_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_identifier_value()) {
    identifier_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.identifier_value(),
      GetArenaNoVirtual());
  }
  string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_string_value()) {
    string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.string_value(),
      GetArenaNoVirtual());
  }
  aggregate_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_aggregate_value()) {
    aggregate_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.aggregate_value(),
      GetArenaNoVirtual());
  }
  ::memcpy(&positive_int_value_, &from.positive_int_value_,
    static_cast<size_t>(reinterpret_cast<char*>(&double_value_) -
    reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
}

void UninterpretedOption::SharedCtor() {
  identifier_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  aggregate_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&positive_int_value_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&double_value_) -
      reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
}

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

void UninterpretedOption::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  identifier_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  aggregate_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

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

const UninterpretedOption& UninterpretedOption::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base);
  return *internal_default_instance();
}


void UninterpretedOption::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  name_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      identifier_value_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      string_value_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      aggregate_value_.ClearNonDefaultToEmpty();
    }
  }
  if (cached_has_bits & 56u) {
    ::memset(&positive_int_value_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&double_value_) -
        reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool UninterpretedOption::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.UninterpretedOption)
  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)) {
      // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_name()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string identifier_value = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_identifier_value()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->identifier_value().data(), static_cast<int>(this->identifier_value().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.UninterpretedOption.identifier_value");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional uint64 positive_int_value = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_positive_int_value();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                 input, &positive_int_value_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int64 negative_int_value = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
          set_has_negative_int_value();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &negative_int_value_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional double double_value = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(49u /* 49 & 0xFF */)) {
          set_has_double_value();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                 input, &double_value_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional bytes string_value = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                input, this->mutable_string_value()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string aggregate_value = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_aggregate_value()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->aggregate_value().data(), static_cast<int>(this->aggregate_value().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.UninterpretedOption.aggregate_value");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption)
  return false;
#undef DO_
}

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

  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->name_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2,
      this->name(static_cast<int>(i)),
      output);
  }

  cached_has_bits = _has_bits_[0];
  // optional string identifier_value = 3;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->identifier_value().data(), static_cast<int>(this->identifier_value().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.identifier_value");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      3, this->identifier_value(), output);
  }

  // optional uint64 positive_int_value = 4;
  if (cached_has_bits & 0x00000008u) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
  }

  // optional int64 negative_int_value = 5;
  if (cached_has_bits & 0x00000010u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
  }

  // optional double double_value = 6;
  if (cached_has_bits & 0x00000020u) {
    ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
  }

  // optional bytes string_value = 7;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
      7, this->string_value(), output);
  }

  // optional string aggregate_value = 8;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->aggregate_value().data(), static_cast<int>(this->aggregate_value().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.aggregate_value");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      8, this->aggregate_value(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption)
}

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

  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->name_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, this->name(static_cast<int>(i)), deterministic, target);
  }

  cached_has_bits = _has_bits_[0];
  // optional string identifier_value = 3;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->identifier_value().data(), static_cast<int>(this->identifier_value().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.identifier_value");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->identifier_value(), target);
  }

  // optional uint64 positive_int_value = 4;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
  }

  // optional int64 negative_int_value = 5;
  if (cached_has_bits & 0x00000010u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
  }

  // optional double double_value = 6;
  if (cached_has_bits & 0x00000020u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
  }

  // optional bytes string_value = 7;
  if (cached_has_bits & 0x00000002u) {
    target =
      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
        7, this->string_value(), target);
  }

  // optional string aggregate_value = 8;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->aggregate_value().data(), static_cast<int>(this->aggregate_value().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.aggregate_value");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        8, this->aggregate_value(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  {
    unsigned int count = static_cast<unsigned int>(this->name_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->name(static_cast<int>(i)));
    }
  }

  if (_has_bits_[0 / 32] & 63u) {
    // optional string identifier_value = 3;
    if (has_identifier_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->identifier_value());
    }

    // optional bytes string_value = 7;
    if (has_string_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::BytesSize(
          this->string_value());
    }

    // optional string aggregate_value = 8;
    if (has_aggregate_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->aggregate_value());
    }

    // optional uint64 positive_int_value = 4;
    if (has_positive_int_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt64Size(
          this->positive_int_value());
    }

    // optional int64 negative_int_value = 5;
    if (has_negative_int_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->negative_int_value());
    }

    // optional double double_value = 6;
    if (has_double_value()) {
      total_size += 1 + 8;
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  name_.MergeFrom(from.name_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 63u) {
    if (cached_has_bits & 0x00000001u) {
      set_identifier_value(from.identifier_value());
    }
    if (cached_has_bits & 0x00000002u) {
      set_string_value(from.string_value());
    }
    if (cached_has_bits & 0x00000004u) {
      set_aggregate_value(from.aggregate_value());
    }
    if (cached_has_bits & 0x00000008u) {
      positive_int_value_ = from.positive_int_value_;
    }
    if (cached_has_bits & 0x00000010u) {
      negative_int_value_ = from.negative_int_value_;
    }
    if (cached_has_bits & 0x00000020u) {
      double_value_ = from.double_value_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

bool UninterpretedOption::IsInitialized() const {
  if (!::google::protobuf::internal::AllAreInitialized(this->name())) return false;
  return true;
}

void UninterpretedOption::Swap(UninterpretedOption* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    UninterpretedOption* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void UninterpretedOption::UnsafeArenaSwap(UninterpretedOption* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void UninterpretedOption::InternalSwap(UninterpretedOption* other) {
  using std::swap;
  CastToBase(&name_)->InternalSwap(CastToBase(&other->name_));
  identifier_value_.Swap(&other->identifier_value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  string_value_.Swap(&other->string_value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  aggregate_value_.Swap(&other->aggregate_value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(positive_int_value_, other->positive_int_value_);
  swap(negative_int_value_, other->negative_int_value_);
  swap(double_value_, other->double_value_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void SourceCodeInfo_Location::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SourceCodeInfo_Location::kPathFieldNumber;
const int SourceCodeInfo_Location::kSpanFieldNumber;
const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber;
const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber;
const int SourceCodeInfo_Location::kLeadingDetachedCommentsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SourceCodeInfo_Location::SourceCodeInfo_Location()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location)
}
SourceCodeInfo_Location::SourceCodeInfo_Location(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  path_(arena),
  span_(arena),
  leading_detached_comments_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location)
}
SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      path_(from.path_),
      span_(from.span_),
      leading_detached_comments_(from.leading_detached_comments_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  leading_comments_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_leading_comments()) {
    leading_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.leading_comments(),
      GetArenaNoVirtual());
  }
  trailing_comments_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_trailing_comments()) {
    trailing_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.trailing_comments(),
      GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
}

void SourceCodeInfo_Location::SharedCtor() {
  leading_comments_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  trailing_comments_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

SourceCodeInfo_Location::~SourceCodeInfo_Location() {
  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
  SharedDtor();
}

void SourceCodeInfo_Location::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  leading_comments_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  trailing_comments_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

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

const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base);
  return *internal_default_instance();
}


void SourceCodeInfo_Location::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  path_.Clear();
  span_.Clear();
  leading_detached_comments_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      leading_comments_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      trailing_comments_.ClearNonDefaultToEmpty();
    }
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool SourceCodeInfo_Location::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.SourceCodeInfo.Location)
  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)) {
      // repeated int32 path = 1 [packed = true];
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_path())));
        } else if (
            static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 10u, input, this->mutable_path())));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated int32 span = 2 [packed = true];
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_span())));
        } else if (
            static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 18u, input, this->mutable_span())));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string leading_comments = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_leading_comments()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->leading_comments().data(), static_cast<int>(this->leading_comments().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.SourceCodeInfo.Location.leading_comments");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string trailing_comments = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_trailing_comments()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->trailing_comments().data(), static_cast<int>(this->trailing_comments().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.SourceCodeInfo.Location.trailing_comments");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // repeated string leading_detached_comments = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_leading_detached_comments()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->leading_detached_comments(this->leading_detached_comments_size() - 1).data(),
            static_cast<int>(this->leading_detached_comments(this->leading_detached_comments_size() - 1).length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.SourceCodeInfo.Location)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo.Location)
  return false;
#undef DO_
}

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

  // repeated int32 path = 1 [packed = true];
  if (this->path_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
        _path_cached_byte_size_));
  }
  for (int i = 0, n = this->path_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
      this->path(i), output);
  }

  // repeated int32 span = 2 [packed = true];
  if (this->span_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
        _span_cached_byte_size_));
  }
  for (int i = 0, n = this->span_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
      this->span(i), output);
  }

  cached_has_bits = _has_bits_[0];
  // optional string leading_comments = 3;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->leading_comments().data(), static_cast<int>(this->leading_comments().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.leading_comments");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      3, this->leading_comments(), output);
  }

  // optional string trailing_comments = 4;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->trailing_comments().data(), static_cast<int>(this->trailing_comments().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.trailing_comments");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      4, this->trailing_comments(), output);
  }

  // repeated string leading_detached_comments = 6;
  for (int i = 0, n = this->leading_detached_comments_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->leading_detached_comments(i).data(), static_cast<int>(this->leading_detached_comments(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
    ::google::protobuf::internal::WireFormatLite::WriteString(
      6, this->leading_detached_comments(i), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location)
}

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

  // repeated int32 path = 1 [packed = true];
  if (this->path_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      1,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
        static_cast< ::google::protobuf::int32>(
            _path_cached_byte_size_), target);
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32NoTagToArray(this->path_, target);
  }

  // repeated int32 span = 2 [packed = true];
  if (this->span_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      2,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
        static_cast< ::google::protobuf::int32>(
            _span_cached_byte_size_), target);
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32NoTagToArray(this->span_, target);
  }

  cached_has_bits = _has_bits_[0];
  // optional string leading_comments = 3;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->leading_comments().data(), static_cast<int>(this->leading_comments().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.leading_comments");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->leading_comments(), target);
  }

  // optional string trailing_comments = 4;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->trailing_comments().data(), static_cast<int>(this->trailing_comments().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.trailing_comments");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->trailing_comments(), target);
  }

  // repeated string leading_detached_comments = 6;
  for (int i = 0, n = this->leading_detached_comments_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->leading_detached_comments(i).data(), static_cast<int>(this->leading_detached_comments(i).length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(6, this->leading_detached_comments(i), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated int32 path = 1 [packed = true];
  {
    size_t data_size = ::google::protobuf::internal::WireFormatLite::
      Int32Size(this->path_);
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
            static_cast< ::google::protobuf::int32>(data_size));
    }
    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _path_cached_byte_size_ = cached_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated int32 span = 2 [packed = true];
  {
    size_t data_size = ::google::protobuf::internal::WireFormatLite::
      Int32Size(this->span_);
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
            static_cast< ::google::protobuf::int32>(data_size));
    }
    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _span_cached_byte_size_ = cached_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

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

  if (_has_bits_[0 / 32] & 3u) {
    // optional string leading_comments = 3;
    if (has_leading_comments()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->leading_comments());
    }

    // optional string trailing_comments = 4;
    if (has_trailing_comments()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->trailing_comments());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  path_.MergeFrom(from.path_);
  span_.MergeFrom(from.span_);
  leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 3u) {
    if (cached_has_bits & 0x00000001u) {
      set_leading_comments(from.leading_comments());
    }
    if (cached_has_bits & 0x00000002u) {
      set_trailing_comments(from.trailing_comments());
    }
  }
}

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

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

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

void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    SourceCodeInfo_Location* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void SourceCodeInfo_Location::UnsafeArenaSwap(SourceCodeInfo_Location* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) {
  using std::swap;
  path_.InternalSwap(&other->path_);
  span_.InternalSwap(&other->span_);
  leading_detached_comments_.InternalSwap(CastToBase(&other->leading_detached_comments_));
  leading_comments_.Swap(&other->leading_comments_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  trailing_comments_.Swap(&other->trailing_comments_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void SourceCodeInfo::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SourceCodeInfo::kLocationFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SourceCodeInfo::SourceCodeInfo()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo)
}
SourceCodeInfo::SourceCodeInfo(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  location_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo)
}
SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      location_(from.location_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
}

void SourceCodeInfo::SharedCtor() {
}

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

void SourceCodeInfo::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const SourceCodeInfo& SourceCodeInfo::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base);
  return *internal_default_instance();
}


void SourceCodeInfo::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  location_.Clear();
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool SourceCodeInfo::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.SourceCodeInfo)
  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)) {
      // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_location()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.SourceCodeInfo)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo)
  return false;
#undef DO_
}

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

  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->location_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1,
      this->location(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo)
}

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

  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->location_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->location(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  {
    unsigned int count = static_cast<unsigned int>(this->location_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->location(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  location_.MergeFrom(from.location_);
}

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

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

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

void SourceCodeInfo::Swap(SourceCodeInfo* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    SourceCodeInfo* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void SourceCodeInfo::UnsafeArenaSwap(SourceCodeInfo* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) {
  using std::swap;
  CastToBase(&location_)->InternalSwap(CastToBase(&other->location_));
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int GeneratedCodeInfo_Annotation::kPathFieldNumber;
const int GeneratedCodeInfo_Annotation::kSourceFileFieldNumber;
const int GeneratedCodeInfo_Annotation::kBeginFieldNumber;
const int GeneratedCodeInfo_Annotation::kEndFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo.Annotation)
}
GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  path_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
}
GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      path_(from.path_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  source_file_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.has_source_file()) {
    source_file_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.source_file(),
      GetArenaNoVirtual());
  }
  ::memcpy(&begin_, &from.begin_,
    static_cast<size_t>(reinterpret_cast<char*>(&end_) -
    reinterpret_cast<char*>(&begin_)) + sizeof(end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
}

void GeneratedCodeInfo_Annotation::SharedCtor() {
  source_file_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&begin_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&end_) -
      reinterpret_cast<char*>(&begin_)) + sizeof(end_));
}

GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() {
  // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation)
  SharedDtor();
}

void GeneratedCodeInfo_Annotation::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
  source_file_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

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

const GeneratedCodeInfo_Annotation& GeneratedCodeInfo_Annotation::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base);
  return *internal_default_instance();
}


void GeneratedCodeInfo_Annotation::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  path_.Clear();
  cached_has_bits = _has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    source_file_.ClearNonDefaultToEmpty();
  }
  if (cached_has_bits & 6u) {
    ::memset(&begin_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&end_) -
        reinterpret_cast<char*>(&begin_)) + sizeof(end_));
  }
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool GeneratedCodeInfo_Annotation::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.GeneratedCodeInfo.Annotation)
  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)) {
      // repeated int32 path = 1 [packed = true];
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_path())));
        } else if (
            static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 10u, input, this->mutable_path())));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional string source_file = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_source_file()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
            this->source_file().data(), static_cast<int>(this->source_file().length()),
            ::google::protobuf::internal::WireFormat::PARSE,
            "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 begin = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
          set_has_begin();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &begin_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // optional int32 end = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
          set_has_end();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.GeneratedCodeInfo.Annotation)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.GeneratedCodeInfo.Annotation)
  return false;
#undef DO_
}

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

  // repeated int32 path = 1 [packed = true];
  if (this->path_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
        _path_cached_byte_size_));
  }
  for (int i = 0, n = this->path_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
      this->path(i), output);
  }

  cached_has_bits = _has_bits_[0];
  // optional string source_file = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->source_file().data(), static_cast<int>(this->source_file().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      2, this->source_file(), output);
  }

  // optional int32 begin = 3;
  if (cached_has_bits & 0x00000002u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->begin(), output);
  }

  // optional int32 end = 4;
  if (cached_has_bits & 0x00000004u) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->end(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo.Annotation)
}

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

  // repeated int32 path = 1 [packed = true];
  if (this->path_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      1,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
        static_cast< ::google::protobuf::int32>(
            _path_cached_byte_size_), target);
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32NoTagToArray(this->path_, target);
  }

  cached_has_bits = _has_bits_[0];
  // optional string source_file = 2;
  if (cached_has_bits & 0x00000001u) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
      this->source_file().data(), static_cast<int>(this->source_file().length()),
      ::google::protobuf::internal::WireFormat::SERIALIZE,
      "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->source_file(), target);
  }

  // optional int32 begin = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->begin(), target);
  }

  // optional int32 end = 4;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->end(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated int32 path = 1 [packed = true];
  {
    size_t data_size = ::google::protobuf::internal::WireFormatLite::
      Int32Size(this->path_);
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
            static_cast< ::google::protobuf::int32>(data_size));
    }
    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _path_cached_byte_size_ = cached_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (_has_bits_[0 / 32] & 7u) {
    // optional string source_file = 2;
    if (has_source_file()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->source_file());
    }

    // optional int32 begin = 3;
    if (has_begin()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->begin());
    }

    // optional int32 end = 4;
    if (has_end()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end());
    }

  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  path_.MergeFrom(from.path_);
  cached_has_bits = from._has_bits_[0];
  if (cached_has_bits & 7u) {
    if (cached_has_bits & 0x00000001u) {
      set_source_file(from.source_file());
    }
    if (cached_has_bits & 0x00000002u) {
      begin_ = from.begin_;
    }
    if (cached_has_bits & 0x00000004u) {
      end_ = from.end_;
    }
    _has_bits_[0] |= cached_has_bits;
  }
}

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

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

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

void GeneratedCodeInfo_Annotation::Swap(GeneratedCodeInfo_Annotation* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    GeneratedCodeInfo_Annotation* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void GeneratedCodeInfo_Annotation::UnsafeArenaSwap(GeneratedCodeInfo_Annotation* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) {
  using std::swap;
  path_.InternalSwap(&other->path_);
  source_file_.Swap(&other->source_file_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(begin_, other->begin_);
  swap(end_, other->end_);
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


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

void GeneratedCodeInfo::InitAsDefaultInstance() {
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int GeneratedCodeInfo::kAnnotationFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

GeneratedCodeInfo::GeneratedCodeInfo()
  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
  ::google::protobuf::internal::InitSCC(
      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo.base);
  SharedCtor();
  // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo)
}
GeneratedCodeInfo::GeneratedCodeInfo(::google::protobuf::Arena* arena)
  : ::google::protobuf::Message(),
  _internal_metadata_(arena),
  annotation_(arena) {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo.base);
  SharedCtor();
  RegisterArenaDtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo)
}
GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(NULL),
      _has_bits_(from._has_bits_),
      annotation_(from.annotation_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo)
}

void GeneratedCodeInfo::SharedCtor() {
}

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

void GeneratedCodeInfo::SharedDtor() {
  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
}

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

const GeneratedCodeInfo& GeneratedCodeInfo::default_instance() {
  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo.base);
  return *internal_default_instance();
}


void GeneratedCodeInfo::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  annotation_.Clear();
  _has_bits_.Clear();
  _internal_metadata_.Clear();
}

bool GeneratedCodeInfo::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.GeneratedCodeInfo)
  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)) {
      // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) ==
            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_annotation()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:google.protobuf.GeneratedCodeInfo)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:google.protobuf.GeneratedCodeInfo)
  return false;
#undef DO_
}

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

  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->annotation_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1,
      this->annotation(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo)
}

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

  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->annotation_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->annotation(static_cast<int>(i)), deterministic, target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo)
  return target;
}

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

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  {
    unsigned int count = static_cast<unsigned int>(this->annotation_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->annotation(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

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

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

  annotation_.MergeFrom(from.annotation_);
}

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

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

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

void GeneratedCodeInfo::Swap(GeneratedCodeInfo* other) {
  if (other == this) return;
  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
    InternalSwap(other);
  } else {
    GeneratedCodeInfo* temp = New(GetArenaNoVirtual());
    temp->MergeFrom(*other);
    other->CopyFrom(*this);
    InternalSwap(temp);
    if (GetArenaNoVirtual() == NULL) {
      delete temp;
    }
  }
}
void GeneratedCodeInfo::UnsafeArenaSwap(GeneratedCodeInfo* other) {
  if (other == this) return;
  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
  InternalSwap(other);
}
void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) {
  using std::swap;
  CastToBase(&annotation_)->InternalSwap(CastToBase(&other->annotation_));
  swap(_has_bits_[0], other->_has_bits_[0]);
  _internal_metadata_.Swap(&other->_internal_metadata_);
}

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


// @@protoc_insertion_point(namespace_scope)
}  // namespace protobuf
}  // namespace google
namespace google {
namespace protobuf {
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::FileDescriptorSet* Arena::CreateMaybeMessage< ::google::protobuf::FileDescriptorSet >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::FileDescriptorSet >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::FileDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::FileDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::FileDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage< ::google::protobuf::DescriptorProto_ExtensionRange >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::DescriptorProto_ExtensionRange >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage< ::google::protobuf::DescriptorProto_ReservedRange >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::DescriptorProto_ReservedRange >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::DescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::DescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::DescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::ExtensionRangeOptions* Arena::CreateMaybeMessage< ::google::protobuf::ExtensionRangeOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::ExtensionRangeOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::FieldDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::FieldDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::FieldDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::OneofDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::OneofDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::OneofDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::EnumDescriptorProto_EnumReservedRange* Arena::CreateMaybeMessage< ::google::protobuf::EnumDescriptorProto_EnumReservedRange >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::EnumDescriptorProto_EnumReservedRange >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::EnumDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::EnumDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::EnumDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::EnumValueDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::EnumValueDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::EnumValueDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::ServiceDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::ServiceDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::ServiceDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::MethodDescriptorProto* Arena::CreateMaybeMessage< ::google::protobuf::MethodDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::MethodDescriptorProto >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::FileOptions* Arena::CreateMaybeMessage< ::google::protobuf::FileOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::FileOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::MessageOptions* Arena::CreateMaybeMessage< ::google::protobuf::MessageOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::MessageOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::FieldOptions* Arena::CreateMaybeMessage< ::google::protobuf::FieldOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::FieldOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::OneofOptions* Arena::CreateMaybeMessage< ::google::protobuf::OneofOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::OneofOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::EnumOptions* Arena::CreateMaybeMessage< ::google::protobuf::EnumOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::EnumOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::EnumValueOptions* Arena::CreateMaybeMessage< ::google::protobuf::EnumValueOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::EnumValueOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::ServiceOptions* Arena::CreateMaybeMessage< ::google::protobuf::ServiceOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::ServiceOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::MethodOptions* Arena::CreateMaybeMessage< ::google::protobuf::MethodOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::MethodOptions >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::UninterpretedOption_NamePart* Arena::CreateMaybeMessage< ::google::protobuf::UninterpretedOption_NamePart >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::UninterpretedOption_NamePart >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::UninterpretedOption* Arena::CreateMaybeMessage< ::google::protobuf::UninterpretedOption >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::UninterpretedOption >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::SourceCodeInfo_Location* Arena::CreateMaybeMessage< ::google::protobuf::SourceCodeInfo_Location >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::SourceCodeInfo_Location >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::SourceCodeInfo* Arena::CreateMaybeMessage< ::google::protobuf::SourceCodeInfo >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::SourceCodeInfo >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::GeneratedCodeInfo_Annotation* Arena::CreateMaybeMessage< ::google::protobuf::GeneratedCodeInfo_Annotation >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::GeneratedCodeInfo_Annotation >(arena);
}
template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::GeneratedCodeInfo* Arena::CreateMaybeMessage< ::google::protobuf::GeneratedCodeInfo >(Arena* arena) {
  return Arena::CreateMessageInternal< ::google::protobuf::GeneratedCodeInfo >(arena);
}
}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)
