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

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3012000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3012004 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/any.pb.h>
#include <google/protobuf/source_context.pb.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto PROTOBUF_EXPORT
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftype_2eproto {
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[5]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
  static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
  static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
};
extern PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto;
PROTOBUF_NAMESPACE_OPEN
class Enum;
class EnumDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumDefaultTypeInternal _Enum_default_instance_;
class EnumValue;
class EnumValueDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumValueDefaultTypeInternal _EnumValue_default_instance_;
class Field;
class FieldDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldDefaultTypeInternal _Field_default_instance_;
class Option;
class OptionDefaultTypeInternal;
PROTOBUF_EXPORT extern OptionDefaultTypeInternal _Option_default_instance_;
class Type;
class TypeDefaultTypeInternal;
PROTOBUF_EXPORT extern TypeDefaultTypeInternal _Type_default_instance_;
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_EXPORT PROTOBUF_NAMESPACE_ID::Enum* Arena::CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::Enum>(Arena*);
template<> PROTOBUF_EXPORT PROTOBUF_NAMESPACE_ID::EnumValue* Arena::CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::EnumValue>(Arena*);
template<> PROTOBUF_EXPORT PROTOBUF_NAMESPACE_ID::Field* Arena::CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::Field>(Arena*);
template<> PROTOBUF_EXPORT PROTOBUF_NAMESPACE_ID::Option* Arena::CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::Option>(Arena*);
template<> PROTOBUF_EXPORT PROTOBUF_NAMESPACE_ID::Type* Arena::CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::Type>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN

enum Field_Kind : int {
  Field_Kind_TYPE_UNKNOWN = 0,
  Field_Kind_TYPE_DOUBLE = 1,
  Field_Kind_TYPE_FLOAT = 2,
  Field_Kind_TYPE_INT64 = 3,
  Field_Kind_TYPE_UINT64 = 4,
  Field_Kind_TYPE_INT32 = 5,
  Field_Kind_TYPE_FIXED64 = 6,
  Field_Kind_TYPE_FIXED32 = 7,
  Field_Kind_TYPE_BOOL = 8,
  Field_Kind_TYPE_STRING = 9,
  Field_Kind_TYPE_GROUP = 10,
  Field_Kind_TYPE_MESSAGE = 11,
  Field_Kind_TYPE_BYTES = 12,
  Field_Kind_TYPE_UINT32 = 13,
  Field_Kind_TYPE_ENUM = 14,
  Field_Kind_TYPE_SFIXED32 = 15,
  Field_Kind_TYPE_SFIXED64 = 16,
  Field_Kind_TYPE_SINT32 = 17,
  Field_Kind_TYPE_SINT64 = 18,
  Field_Kind_Field_Kind_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
  Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
};
PROTOBUF_EXPORT bool Field_Kind_IsValid(int value);
constexpr Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN;
constexpr Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64;
constexpr int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor();
template<typename T>
inline const std::string& Field_Kind_Name(T enum_t_value) {
  static_assert(::std::is_same<T, Field_Kind>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function Field_Kind_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    Field_Kind_descriptor(), enum_t_value);
}
inline bool Field_Kind_Parse(
    const std::string& name, Field_Kind* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Field_Kind>(
    Field_Kind_descriptor(), name, value);
}
enum Field_Cardinality : int {
  Field_Cardinality_CARDINALITY_UNKNOWN = 0,
  Field_Cardinality_CARDINALITY_OPTIONAL = 1,
  Field_Cardinality_CARDINALITY_REQUIRED = 2,
  Field_Cardinality_CARDINALITY_REPEATED = 3,
  Field_Cardinality_Field_Cardinality_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
  Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
};
PROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value);
constexpr Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN;
constexpr Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED;
constexpr int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Cardinality_descriptor();
template<typename T>
inline const std::string& Field_Cardinality_Name(T enum_t_value) {
  static_assert(::std::is_same<T, Field_Cardinality>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function Field_Cardinality_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    Field_Cardinality_descriptor(), enum_t_value);
}
inline bool Field_Cardinality_Parse(
    const std::string& name, Field_Cardinality* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Field_Cardinality>(
    Field_Cardinality_descriptor(), name, value);
}
enum Syntax : int {
  SYNTAX_PROTO2 = 0,
  SYNTAX_PROTO3 = 1,
  Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
  Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
};
PROTOBUF_EXPORT bool Syntax_IsValid(int value);
constexpr Syntax Syntax_MIN = SYNTAX_PROTO2;
constexpr Syntax Syntax_MAX = SYNTAX_PROTO3;
constexpr int Syntax_ARRAYSIZE = Syntax_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Syntax_descriptor();
template<typename T>
inline const std::string& Syntax_Name(T enum_t_value) {
  static_assert(::std::is_same<T, Syntax>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function Syntax_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    Syntax_descriptor(), enum_t_value);
}
inline bool Syntax_Parse(
    const std::string& name, Syntax* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Syntax>(
    Syntax_descriptor(), name, value);
}
// ===================================================================

class PROTOBUF_EXPORT Type PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ {
 public:
  inline Type() : Type(nullptr) {};
  virtual ~Type();

  Type(const Type& from);
  Type(Type&& from) noexcept
    : Type() {
    *this = ::std::move(from);
  }

  inline Type& operator=(const Type& from) {
    CopyFrom(from);
    return *this;
  }
  inline Type& operator=(Type&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const Type& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Type* internal_default_instance() {
    return reinterpret_cast<const Type*>(
               &_Type_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(Type& a, Type& b) {
    a.Swap(&b);
  }
  inline void Swap(Type* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Type* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline Type* New() const final {
    return CreateMaybeMessage<Type>(nullptr);
  }

  Type* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Type>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Type& from);
  void MergeFrom(const Type& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Type* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.Type";
  }
  protected:
  explicit Type(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2fprotobuf_2ftype_2eproto);
    return ::descriptor_table_google_2fprotobuf_2ftype_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFieldsFieldNumber = 2,
    kOneofsFieldNumber = 3,
    kOptionsFieldNumber = 4,
    kNameFieldNumber = 1,
    kSourceContextFieldNumber = 5,
    kSyntaxFieldNumber = 6,
  };
  // repeated .google.protobuf.Field fields = 2;
  int fields_size() const;
  private:
  int _internal_fields_size() const;
  public:
  void clear_fields();
  PROTOBUF_NAMESPACE_ID::Field* mutable_fields(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Field >*
      mutable_fields();
  private:
  const PROTOBUF_NAMESPACE_ID::Field& _internal_fields(int index) const;
  PROTOBUF_NAMESPACE_ID::Field* _internal_add_fields();
  public:
  const PROTOBUF_NAMESPACE_ID::Field& fields(int index) const;
  PROTOBUF_NAMESPACE_ID::Field* add_fields();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Field >&
      fields() const;

  // repeated string oneofs = 3;
  int oneofs_size() const;
  private:
  int _internal_oneofs_size() const;
  public:
  void clear_oneofs();
  const std::string& oneofs(int index) const;
  std::string* mutable_oneofs(int index);
  void set_oneofs(int index, const std::string& value);
  void set_oneofs(int index, std::string&& value);
  void set_oneofs(int index, const char* value);
  void set_oneofs(int index, const char* value, size_t size);
  std::string* add_oneofs();
  void add_oneofs(const std::string& value);
  void add_oneofs(std::string&& value);
  void add_oneofs(const char* value);
  void add_oneofs(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& oneofs() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_oneofs();
  private:
  const std::string& _internal_oneofs(int index) const;
  std::string* _internal_add_oneofs();
  public:

  // repeated .google.protobuf.Option options = 4;
  int options_size() const;
  private:
  int _internal_options_size() const;
  public:
  void clear_options();
  PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
      mutable_options();
  private:
  const PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
  public:
  const PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* add_options();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  const std::string& name() const;
  void set_name(const std::string& value);
  void set_name(std::string&& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_name();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // .google.protobuf.SourceContext source_context = 5;
  bool has_source_context() const;
  private:
  bool _internal_has_source_context() const;
  public:
  void clear_source_context();
  const PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
  PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
  PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
  void set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
  private:
  const PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const;
  PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context();
  public:
  void unsafe_arena_set_allocated_source_context(
      PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
  PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context();

  // .google.protobuf.Syntax syntax = 6;
  void clear_syntax();
  PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
  void set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
  private:
  PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const;
  void _internal_set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.Type)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Field > fields_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> oneofs_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option > options_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  PROTOBUF_NAMESPACE_ID::SourceContext* source_context_;
  int syntax_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT Field PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ {
 public:
  inline Field() : Field(nullptr) {};
  virtual ~Field();

  Field(const Field& from);
  Field(Field&& from) noexcept
    : Field() {
    *this = ::std::move(from);
  }

  inline Field& operator=(const Field& from) {
    CopyFrom(from);
    return *this;
  }
  inline Field& operator=(Field&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const Field& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Field* internal_default_instance() {
    return reinterpret_cast<const Field*>(
               &_Field_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(Field& a, Field& b) {
    a.Swap(&b);
  }
  inline void Swap(Field* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Field* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline Field* New() const final {
    return CreateMaybeMessage<Field>(nullptr);
  }

  Field* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Field>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Field& from);
  void MergeFrom(const Field& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Field* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.Field";
  }
  protected:
  explicit Field(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2fprotobuf_2ftype_2eproto);
    return ::descriptor_table_google_2fprotobuf_2ftype_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

  // nested types ----------------------------------------------------

  typedef Field_Kind Kind;
  static constexpr Kind TYPE_UNKNOWN =
    Field_Kind_TYPE_UNKNOWN;
  static constexpr Kind TYPE_DOUBLE =
    Field_Kind_TYPE_DOUBLE;
  static constexpr Kind TYPE_FLOAT =
    Field_Kind_TYPE_FLOAT;
  static constexpr Kind TYPE_INT64 =
    Field_Kind_TYPE_INT64;
  static constexpr Kind TYPE_UINT64 =
    Field_Kind_TYPE_UINT64;
  static constexpr Kind TYPE_INT32 =
    Field_Kind_TYPE_INT32;
  static constexpr Kind TYPE_FIXED64 =
    Field_Kind_TYPE_FIXED64;
  static constexpr Kind TYPE_FIXED32 =
    Field_Kind_TYPE_FIXED32;
  static constexpr Kind TYPE_BOOL =
    Field_Kind_TYPE_BOOL;
  static constexpr Kind TYPE_STRING =
    Field_Kind_TYPE_STRING;
  static constexpr Kind TYPE_GROUP =
    Field_Kind_TYPE_GROUP;
  static constexpr Kind TYPE_MESSAGE =
    Field_Kind_TYPE_MESSAGE;
  static constexpr Kind TYPE_BYTES =
    Field_Kind_TYPE_BYTES;
  static constexpr Kind TYPE_UINT32 =
    Field_Kind_TYPE_UINT32;
  static constexpr Kind TYPE_ENUM =
    Field_Kind_TYPE_ENUM;
  static constexpr Kind TYPE_SFIXED32 =
    Field_Kind_TYPE_SFIXED32;
  static constexpr Kind TYPE_SFIXED64 =
    Field_Kind_TYPE_SFIXED64;
  static constexpr Kind TYPE_SINT32 =
    Field_Kind_TYPE_SINT32;
  static constexpr Kind TYPE_SINT64 =
    Field_Kind_TYPE_SINT64;
  static inline bool Kind_IsValid(int value) {
    return Field_Kind_IsValid(value);
  }
  static constexpr Kind Kind_MIN =
    Field_Kind_Kind_MIN;
  static constexpr Kind Kind_MAX =
    Field_Kind_Kind_MAX;
  static constexpr int Kind_ARRAYSIZE =
    Field_Kind_Kind_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  Kind_descriptor() {
    return Field_Kind_descriptor();
  }
  template<typename T>
  static inline const std::string& Kind_Name(T enum_t_value) {
    static_assert(::std::is_same<T, Kind>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function Kind_Name.");
    return Field_Kind_Name(enum_t_value);
  }
  static inline bool Kind_Parse(const std::string& name,
      Kind* value) {
    return Field_Kind_Parse(name, value);
  }

  typedef Field_Cardinality Cardinality;
  static constexpr Cardinality CARDINALITY_UNKNOWN =
    Field_Cardinality_CARDINALITY_UNKNOWN;
  static constexpr Cardinality CARDINALITY_OPTIONAL =
    Field_Cardinality_CARDINALITY_OPTIONAL;
  static constexpr Cardinality CARDINALITY_REQUIRED =
    Field_Cardinality_CARDINALITY_REQUIRED;
  static constexpr Cardinality CARDINALITY_REPEATED =
    Field_Cardinality_CARDINALITY_REPEATED;
  static inline bool Cardinality_IsValid(int value) {
    return Field_Cardinality_IsValid(value);
  }
  static constexpr Cardinality Cardinality_MIN =
    Field_Cardinality_Cardinality_MIN;
  static constexpr Cardinality Cardinality_MAX =
    Field_Cardinality_Cardinality_MAX;
  static constexpr int Cardinality_ARRAYSIZE =
    Field_Cardinality_Cardinality_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  Cardinality_descriptor() {
    return Field_Cardinality_descriptor();
  }
  template<typename T>
  static inline const std::string& Cardinality_Name(T enum_t_value) {
    static_assert(::std::is_same<T, Cardinality>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function Cardinality_Name.");
    return Field_Cardinality_Name(enum_t_value);
  }
  static inline bool Cardinality_Parse(const std::string& name,
      Cardinality* value) {
    return Field_Cardinality_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  enum : int {
    kOptionsFieldNumber = 9,
    kNameFieldNumber = 4,
    kTypeUrlFieldNumber = 6,
    kJsonNameFieldNumber = 10,
    kDefaultValueFieldNumber = 11,
    kKindFieldNumber = 1,
    kCardinalityFieldNumber = 2,
    kNumberFieldNumber = 3,
    kOneofIndexFieldNumber = 7,
    kPackedFieldNumber = 8,
  };
  // repeated .google.protobuf.Option options = 9;
  int options_size() const;
  private:
  int _internal_options_size() const;
  public:
  void clear_options();
  PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
      mutable_options();
  private:
  const PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
  public:
  const PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* add_options();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >&
      options() const;

  // string name = 4;
  void clear_name();
  const std::string& name() const;
  void set_name(const std::string& value);
  void set_name(std::string&& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_name();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // string type_url = 6;
  void clear_type_url();
  const std::string& type_url() const;
  void set_type_url(const std::string& value);
  void set_type_url(std::string&& value);
  void set_type_url(const char* value);
  void set_type_url(const char* value, size_t size);
  std::string* mutable_type_url();
  std::string* release_type_url();
  void set_allocated_type_url(std::string* type_url);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_type_url();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_type_url(
      std::string* type_url);
  private:
  const std::string& _internal_type_url() const;
  void _internal_set_type_url(const std::string& value);
  std::string* _internal_mutable_type_url();
  public:

  // string json_name = 10;
  void clear_json_name();
  const std::string& json_name() const;
  void set_json_name(const std::string& value);
  void set_json_name(std::string&& value);
  void set_json_name(const char* value);
  void set_json_name(const char* value, size_t size);
  std::string* mutable_json_name();
  std::string* release_json_name();
  void set_allocated_json_name(std::string* json_name);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_json_name();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_json_name(
      std::string* json_name);
  private:
  const std::string& _internal_json_name() const;
  void _internal_set_json_name(const std::string& value);
  std::string* _internal_mutable_json_name();
  public:

  // string default_value = 11;
  void clear_default_value();
  const std::string& default_value() const;
  void set_default_value(const std::string& value);
  void set_default_value(std::string&& value);
  void set_default_value(const char* value);
  void set_default_value(const char* value, size_t size);
  std::string* mutable_default_value();
  std::string* release_default_value();
  void set_allocated_default_value(std::string* default_value);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_default_value();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_default_value(
      std::string* default_value);
  private:
  const std::string& _internal_default_value() const;
  void _internal_set_default_value(const std::string& value);
  std::string* _internal_mutable_default_value();
  public:

  // .google.protobuf.Field.Kind kind = 1;
  void clear_kind();
  PROTOBUF_NAMESPACE_ID::Field_Kind kind() const;
  void set_kind(PROTOBUF_NAMESPACE_ID::Field_Kind value);
  private:
  PROTOBUF_NAMESPACE_ID::Field_Kind _internal_kind() const;
  void _internal_set_kind(PROTOBUF_NAMESPACE_ID::Field_Kind value);
  public:

  // .google.protobuf.Field.Cardinality cardinality = 2;
  void clear_cardinality();
  PROTOBUF_NAMESPACE_ID::Field_Cardinality cardinality() const;
  void set_cardinality(PROTOBUF_NAMESPACE_ID::Field_Cardinality value);
  private:
  PROTOBUF_NAMESPACE_ID::Field_Cardinality _internal_cardinality() const;
  void _internal_set_cardinality(PROTOBUF_NAMESPACE_ID::Field_Cardinality value);
  public:

  // int32 number = 3;
  void clear_number();
  ::PROTOBUF_NAMESPACE_ID::int32 number() const;
  void set_number(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_number() const;
  void _internal_set_number(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // int32 oneof_index = 7;
  void clear_oneof_index();
  ::PROTOBUF_NAMESPACE_ID::int32 oneof_index() const;
  void set_oneof_index(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_oneof_index() const;
  void _internal_set_oneof_index(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // bool packed = 8;
  void clear_packed();
  bool packed() const;
  void set_packed(bool value);
  private:
  bool _internal_packed() const;
  void _internal_set_packed(bool value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.Field)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option > options_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr json_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr default_value_;
  int kind_;
  int cardinality_;
  ::PROTOBUF_NAMESPACE_ID::int32 number_;
  ::PROTOBUF_NAMESPACE_ID::int32 oneof_index_;
  bool packed_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT Enum PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ {
 public:
  inline Enum() : Enum(nullptr) {};
  virtual ~Enum();

  Enum(const Enum& from);
  Enum(Enum&& from) noexcept
    : Enum() {
    *this = ::std::move(from);
  }

  inline Enum& operator=(const Enum& from) {
    CopyFrom(from);
    return *this;
  }
  inline Enum& operator=(Enum&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const Enum& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Enum* internal_default_instance() {
    return reinterpret_cast<const Enum*>(
               &_Enum_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(Enum& a, Enum& b) {
    a.Swap(&b);
  }
  inline void Swap(Enum* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Enum* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline Enum* New() const final {
    return CreateMaybeMessage<Enum>(nullptr);
  }

  Enum* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Enum>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Enum& from);
  void MergeFrom(const Enum& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Enum* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.Enum";
  }
  protected:
  explicit Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2fprotobuf_2ftype_2eproto);
    return ::descriptor_table_google_2fprotobuf_2ftype_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kEnumvalueFieldNumber = 2,
    kOptionsFieldNumber = 3,
    kNameFieldNumber = 1,
    kSourceContextFieldNumber = 4,
    kSyntaxFieldNumber = 5,
  };
  // repeated .google.protobuf.EnumValue enumvalue = 2;
  int enumvalue_size() const;
  private:
  int _internal_enumvalue_size() const;
  public:
  void clear_enumvalue();
  PROTOBUF_NAMESPACE_ID::EnumValue* mutable_enumvalue(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::EnumValue >*
      mutable_enumvalue();
  private:
  const PROTOBUF_NAMESPACE_ID::EnumValue& _internal_enumvalue(int index) const;
  PROTOBUF_NAMESPACE_ID::EnumValue* _internal_add_enumvalue();
  public:
  const PROTOBUF_NAMESPACE_ID::EnumValue& enumvalue(int index) const;
  PROTOBUF_NAMESPACE_ID::EnumValue* add_enumvalue();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::EnumValue >&
      enumvalue() const;

  // repeated .google.protobuf.Option options = 3;
  int options_size() const;
  private:
  int _internal_options_size() const;
  public:
  void clear_options();
  PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
      mutable_options();
  private:
  const PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
  public:
  const PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* add_options();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  const std::string& name() const;
  void set_name(const std::string& value);
  void set_name(std::string&& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_name();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // .google.protobuf.SourceContext source_context = 4;
  bool has_source_context() const;
  private:
  bool _internal_has_source_context() const;
  public:
  void clear_source_context();
  const PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
  PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
  PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
  void set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
  private:
  const PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const;
  PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context();
  public:
  void unsafe_arena_set_allocated_source_context(
      PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
  PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context();

  // .google.protobuf.Syntax syntax = 5;
  void clear_syntax();
  PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
  void set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
  private:
  PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const;
  void _internal_set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.Enum)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::EnumValue > enumvalue_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option > options_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  PROTOBUF_NAMESPACE_ID::SourceContext* source_context_;
  int syntax_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumValue PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ {
 public:
  inline EnumValue() : EnumValue(nullptr) {};
  virtual ~EnumValue();

  EnumValue(const EnumValue& from);
  EnumValue(EnumValue&& from) noexcept
    : EnumValue() {
    *this = ::std::move(from);
  }

  inline EnumValue& operator=(const EnumValue& from) {
    CopyFrom(from);
    return *this;
  }
  inline EnumValue& operator=(EnumValue&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const EnumValue& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const EnumValue* internal_default_instance() {
    return reinterpret_cast<const EnumValue*>(
               &_EnumValue_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  friend void swap(EnumValue& a, EnumValue& b) {
    a.Swap(&b);
  }
  inline void Swap(EnumValue* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumValue* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline EnumValue* New() const final {
    return CreateMaybeMessage<EnumValue>(nullptr);
  }

  EnumValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<EnumValue>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const EnumValue& from);
  void MergeFrom(const EnumValue& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumValue* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.EnumValue";
  }
  protected:
  explicit EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2fprotobuf_2ftype_2eproto);
    return ::descriptor_table_google_2fprotobuf_2ftype_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kOptionsFieldNumber = 3,
    kNameFieldNumber = 1,
    kNumberFieldNumber = 2,
  };
  // repeated .google.protobuf.Option options = 3;
  int options_size() const;
  private:
  int _internal_options_size() const;
  public:
  void clear_options();
  PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
      mutable_options();
  private:
  const PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
  public:
  const PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
  PROTOBUF_NAMESPACE_ID::Option* add_options();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  const std::string& name() const;
  void set_name(const std::string& value);
  void set_name(std::string&& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_name();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // int32 number = 2;
  void clear_number();
  ::PROTOBUF_NAMESPACE_ID::int32 number() const;
  void set_number(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_number() const;
  void _internal_set_number(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValue)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option > options_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  ::PROTOBUF_NAMESPACE_ID::int32 number_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT Option PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ {
 public:
  inline Option() : Option(nullptr) {};
  virtual ~Option();

  Option(const Option& from);
  Option(Option&& from) noexcept
    : Option() {
    *this = ::std::move(from);
  }

  inline Option& operator=(const Option& from) {
    CopyFrom(from);
    return *this;
  }
  inline Option& operator=(Option&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return GetMetadataStatic().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return GetMetadataStatic().reflection;
  }
  static const Option& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Option* internal_default_instance() {
    return reinterpret_cast<const Option*>(
               &_Option_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  friend void swap(Option& a, Option& b) {
    a.Swap(&b);
  }
  inline void Swap(Option* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Option* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline Option* New() const final {
    return CreateMaybeMessage<Option>(nullptr);
  }

  Option* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Option>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Option& from);
  void MergeFrom(const Option& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Option* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.Option";
  }
  protected:
  explicit Option(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
  private:
  static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() {
    ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2fprotobuf_2ftype_2eproto);
    return ::descriptor_table_google_2fprotobuf_2ftype_2eproto.file_level_metadata[kIndexInFileMessages];
  }

  public:

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kNameFieldNumber = 1,
    kValueFieldNumber = 2,
  };
  // string name = 1;
  void clear_name();
  const std::string& name() const;
  void set_name(const std::string& value);
  void set_name(std::string&& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  std::string* unsafe_arena_release_name();
  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // .google.protobuf.Any value = 2;
  bool has_value() const;
  private:
  bool _internal_has_value() const;
  public:
  void clear_value();
  const PROTOBUF_NAMESPACE_ID::Any& value() const;
  PROTOBUF_NAMESPACE_ID::Any* release_value();
  PROTOBUF_NAMESPACE_ID::Any* mutable_value();
  void set_allocated_value(PROTOBUF_NAMESPACE_ID::Any* value);
  private:
  const PROTOBUF_NAMESPACE_ID::Any& _internal_value() const;
  PROTOBUF_NAMESPACE_ID::Any* _internal_mutable_value();
  public:
  void unsafe_arena_set_allocated_value(
      PROTOBUF_NAMESPACE_ID::Any* value);
  PROTOBUF_NAMESPACE_ID::Any* unsafe_arena_release_value();

  // @@protoc_insertion_point(class_scope:google.protobuf.Option)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  PROTOBUF_NAMESPACE_ID::Any* value_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};
// ===================================================================


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

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// Type

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

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

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

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

// .google.protobuf.SourceContext source_context = 5;
inline bool Type::_internal_has_source_context() const {
  return this != internal_default_instance() && source_context_ != nullptr;
}
inline bool Type::has_source_context() const {
  return _internal_has_source_context();
}
inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::_internal_source_context() const {
  const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext*>(
      &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
}
inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
  return _internal_source_context();
}
inline void Type::unsafe_arena_set_allocated_source_context(
    PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
  }
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.source_context)
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::release_source_context() {
  auto temp = unsafe_arena_release_source_context();
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::unsafe_arena_release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context)
  
  PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
  source_context_ = nullptr;
  return temp;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::_internal_mutable_source_context() {
  
  if (source_context_ == nullptr) {
    auto* p = CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::SourceContext>(GetArena());
    source_context_ = p;
  }
  return source_context_;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::mutable_source_context() {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context)
  return _internal_mutable_source_context();
}
inline void Type::set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
  }
  if (source_context) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)->GetArena();
    if (message_arena != submessage_arena) {
      source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, source_context, submessage_arena);
    }
    
  } else {
    
  }
  source_context_ = source_context;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
}

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

// -------------------------------------------------------------------

// Field

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

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

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

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

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

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

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

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

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

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

// -------------------------------------------------------------------

// Enum

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

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

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

// .google.protobuf.SourceContext source_context = 4;
inline bool Enum::_internal_has_source_context() const {
  return this != internal_default_instance() && source_context_ != nullptr;
}
inline bool Enum::has_source_context() const {
  return _internal_has_source_context();
}
inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_internal_source_context() const {
  const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_;
  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::SourceContext*>(
      &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
}
inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
  return _internal_source_context();
}
inline void Enum::unsafe_arena_set_allocated_source_context(
    PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
  }
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.source_context)
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::release_source_context() {
  auto temp = unsafe_arena_release_source_context();
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::unsafe_arena_release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context)
  
  PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_;
  source_context_ = nullptr;
  return temp;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::_internal_mutable_source_context() {
  
  if (source_context_ == nullptr) {
    auto* p = CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::SourceContext>(GetArena());
    source_context_ = p;
  }
  return source_context_;
}
inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::mutable_source_context() {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context)
  return _internal_mutable_source_context();
}
inline void Enum::set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_);
  }
  if (source_context) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)->GetArena();
    if (message_arena != submessage_arena) {
      source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, source_context, submessage_arena);
    }
    
  } else {
    
  }
  source_context_ = source_context;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
}

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

// -------------------------------------------------------------------

// EnumValue

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

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

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

// -------------------------------------------------------------------

// Option

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

// .google.protobuf.Any value = 2;
inline bool Option::_internal_has_value() const {
  return this != internal_default_instance() && value_ != nullptr;
}
inline bool Option::has_value() const {
  return _internal_has_value();
}
inline const PROTOBUF_NAMESPACE_ID::Any& Option::_internal_value() const {
  const PROTOBUF_NAMESPACE_ID::Any* p = value_;
  return p != nullptr ? *p : *reinterpret_cast<const PROTOBUF_NAMESPACE_ID::Any*>(
      &PROTOBUF_NAMESPACE_ID::_Any_default_instance_);
}
inline const PROTOBUF_NAMESPACE_ID::Any& Option::value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Option.value)
  return _internal_value();
}
inline void Option::unsafe_arena_set_allocated_value(
    PROTOBUF_NAMESPACE_ID::Any* value) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_);
  }
  value_ = value;
  if (value) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.value)
}
inline PROTOBUF_NAMESPACE_ID::Any* Option::release_value() {
  auto temp = unsafe_arena_release_value();
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline PROTOBUF_NAMESPACE_ID::Any* Option::unsafe_arena_release_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Option.value)
  
  PROTOBUF_NAMESPACE_ID::Any* temp = value_;
  value_ = nullptr;
  return temp;
}
inline PROTOBUF_NAMESPACE_ID::Any* Option::_internal_mutable_value() {
  
  if (value_ == nullptr) {
    auto* p = CreateMaybeMessage<PROTOBUF_NAMESPACE_ID::Any>(GetArena());
    value_ = p;
  }
  return value_;
}
inline PROTOBUF_NAMESPACE_ID::Any* Option::mutable_value() {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value)
  return _internal_mutable_value();
}
inline void Option::set_allocated_value(PROTOBUF_NAMESPACE_ID::Any* value) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_);
  }
  if (value) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, value, submessage_arena);
    }
    
  } else {
    
  }
  value_ = value;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value)
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

PROTOBUF_NAMESPACE_CLOSE

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< PROTOBUF_NAMESPACE_ID::Field_Kind> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< PROTOBUF_NAMESPACE_ID::Field_Kind>() {
  return PROTOBUF_NAMESPACE_ID::Field_Kind_descriptor();
}
template <> struct is_proto_enum< PROTOBUF_NAMESPACE_ID::Field_Cardinality> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< PROTOBUF_NAMESPACE_ID::Field_Cardinality>() {
  return PROTOBUF_NAMESPACE_ID::Field_Cardinality_descriptor();
}
template <> struct is_proto_enum< PROTOBUF_NAMESPACE_ID::Syntax> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< PROTOBUF_NAMESPACE_ID::Syntax>() {
  return PROTOBUF_NAMESPACE_ID::Syntax_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
