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

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto_2epb_2eh

#include <limits>
#include <string>
#include <type_traits>

#include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 3021000
#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  // PROTOBUF_VERSION

#if 3021007 < 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  // PROTOBUF_MIN_PROTOC_VERSION
#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_util.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)

// Must be included last.
#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 uint32_t offsets[];
};
PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable
    descriptor_table_google_2fprotobuf_2ftype_2eproto;
PROTOBUF_NAMESPACE_OPEN
class Enum;
struct EnumDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumDefaultTypeInternal _Enum_default_instance_;
class EnumValue;
struct EnumValueDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumValueDefaultTypeInternal _EnumValue_default_instance_;
class Field;
struct FieldDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldDefaultTypeInternal _Field_default_instance_;
class Option;
struct OptionDefaultTypeInternal;
PROTOBUF_EXPORT extern OptionDefaultTypeInternal _Option_default_instance_;
class Type;
struct TypeDefaultTypeInternal;
PROTOBUF_EXPORT extern TypeDefaultTypeInternal _Type_default_instance_;
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<int32_t>::min(),
  Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 Field_Kind_Name(static_cast<Field_Kind>(enum_t_value));
}
template<>
inline const std::string& Field_Kind_Name(Field_Kind value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
    <Field_Kind_descriptor, 0, 18>(static_cast<int>(value));
}
inline bool Field_Kind_Parse(
    ::absl::string_view 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<int32_t>::min(),
  Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 Field_Cardinality_Name(static_cast<Field_Cardinality>(enum_t_value));
}
template<>
inline const std::string& Field_Cardinality_Name(Field_Cardinality value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
    <Field_Cardinality_descriptor, 0, 3>(static_cast<int>(value));
}
inline bool Field_Cardinality_Parse(
    ::absl::string_view 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<int32_t>::min(),
  Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::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 Syntax_Name(static_cast<Syntax>(enum_t_value));
}
template<>
inline const std::string& Syntax_Name(Syntax value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum
    <Syntax_descriptor, 0, 1>(static_cast<int>(value));
}
inline bool Syntax_Parse(
    ::absl::string_view name, Syntax* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<Syntax>(
    Syntax_descriptor(), name, value);
}

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


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

class PROTOBUF_EXPORT Type final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ {
 public:
  inline Type() : Type(nullptr) {}
  ~Type() override;
  explicit PROTOBUF_CONSTEXPR Type(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  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 (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Type& default_instance() {
    return *internal_default_instance();
  }
  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;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Type* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Type* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Type>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Type& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Type& from) {
    Type::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  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;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Type* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Type";
  }
  protected:
  explicit Type(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE 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_NODISCARD ::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_;
  struct Impl_ {
    ::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_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT Field final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ {
 public:
  inline Field() : Field(nullptr) {}
  ~Field() override;
  explicit PROTOBUF_CONSTEXPR Field(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  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 (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Field& default_instance() {
    return *internal_default_instance();
  }
  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;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Field* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Field* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Field>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Field& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Field& from) {
    Field::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  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;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Field* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Field";
  }
  protected:
  explicit Field(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // 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(::absl::string_view 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(::absl::string_view 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_type_url(ArgT0&& arg0, ArgT... args);
  std::string* mutable_type_url();
  PROTOBUF_NODISCARD std::string* release_type_url();
  void set_allocated_type_url(std::string* type_url);
  private:
  const std::string& _internal_type_url() const;
  inline PROTOBUF_ALWAYS_INLINE 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_json_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_json_name();
  PROTOBUF_NODISCARD std::string* release_json_name();
  void set_allocated_json_name(std::string* json_name);
  private:
  const std::string& _internal_json_name() const;
  inline PROTOBUF_ALWAYS_INLINE 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_default_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_default_value();
  PROTOBUF_NODISCARD std::string* release_default_value();
  void set_allocated_default_value(std::string* default_value);
  private:
  const std::string& _internal_default_value() const;
  inline PROTOBUF_ALWAYS_INLINE 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();
  int32_t number() const;
  void set_number(int32_t value);
  private:
  int32_t _internal_number() const;
  void _internal_set_number(int32_t value);
  public:

  // int32 oneof_index = 7;
  void clear_oneof_index();
  int32_t oneof_index() const;
  void set_oneof_index(int32_t value);
  private:
  int32_t _internal_oneof_index() const;
  void _internal_set_oneof_index(int32_t 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_;
  struct Impl_ {
    ::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_;
    int32_t number_;
    int32_t oneof_index_;
    bool packed_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT Enum final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ {
 public:
  inline Enum() : Enum(nullptr) {}
  ~Enum() override;
  explicit PROTOBUF_CONSTEXPR Enum(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  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 (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Enum& default_instance() {
    return *internal_default_instance();
  }
  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;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Enum* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Enum* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Enum>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Enum& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Enum& from) {
    Enum::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  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;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Enum* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Enum";
  }
  protected:
  explicit Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE 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_NODISCARD ::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_;
  struct Impl_ {
    ::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_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumValue final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ {
 public:
  inline EnumValue() : EnumValue(nullptr) {}
  ~EnumValue() override;
  explicit PROTOBUF_CONSTEXPR EnumValue(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  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 (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const EnumValue& default_instance() {
    return *internal_default_instance();
  }
  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;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumValue* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  EnumValue* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<EnumValue>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const EnumValue& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const EnumValue& from) {
    EnumValue::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  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;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumValue* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.EnumValue";
  }
  protected:
  explicit EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // 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;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // int32 number = 2;
  void clear_number();
  int32_t number() const;
  void set_number(int32_t value);
  private:
  int32_t _internal_number() const;
  void _internal_set_number(int32_t 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_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    int32_t number_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT Option final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ {
 public:
  inline Option() : Option(nullptr) {}
  ~Option() override;
  explicit PROTOBUF_CONSTEXPR Option(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  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 (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Option& default_instance() {
    return *internal_default_instance();
  }
  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;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Option* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Option* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Option>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Option& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Option& from) {
    Option::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  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;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Option* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Option";
  }
  protected:
  explicit Option(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kNameFieldNumber = 1,
    kValueFieldNumber = 2,
  };
  // string name = 1;
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE 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_NODISCARD ::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_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::Any* value_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  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() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Type::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Type::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Type.name)
}
inline std::string* Type::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name)
  return _s;
}
inline const std::string& Type::_internal_name() const {
  return _impl_.name_.Get();
}
inline void Type::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Type::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Type::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
  return _impl_.name_.Release();
}
inline void Type::set_allocated_name(std::string* name) {
  if (name != nullptr) {

  } else {

  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name)
}

// repeated .google.protobuf.Field fields = 2;
inline int Type::_internal_fields_size() const {
  return _impl_.fields_.size();
}
inline int Type::fields_size() const {
  return _internal_fields_size();
}
inline void Type::clear_fields() {
  _impl_.fields_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Field* Type::mutable_fields(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields)
  return _impl_.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 &_impl_.fields_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Field& Type::_internal_fields(int index) const {
  return _impl_.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 _impl_.fields_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Field* Type::add_fields() {
  ::PROTOBUF_NAMESPACE_ID::Field* _add = _internal_add_fields();
  // @@protoc_insertion_point(field_add:google.protobuf.Type.fields)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Field >&
Type::fields() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
  return _impl_.fields_;
}

// repeated string oneofs = 3;
inline int Type::_internal_oneofs_size() const {
  return _impl_.oneofs_.size();
}
inline int Type::oneofs_size() const {
  return _internal_oneofs_size();
}
inline void Type::clear_oneofs() {
  _impl_.oneofs_.Clear();
}
inline std::string* Type::add_oneofs() {
  std::string* _s = _internal_add_oneofs();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs)
  return _s;
}
inline const std::string& Type::_internal_oneofs(int index) const {
  return _impl_.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 _impl_.oneofs_.Mutable(index);
}
inline void Type::set_oneofs(int index, const std::string& value) {
  _impl_.oneofs_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
}
inline void Type::set_oneofs(int index, std::string&& value) {
  _impl_.oneofs_.Mutable(index)->assign(std::move(value));
  // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
}
inline void Type::set_oneofs(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);  _impl_.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) {
  _impl_.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 _impl_.oneofs_.Add();
}
inline void Type::add_oneofs(const std::string& value) {
  _impl_.oneofs_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
}
inline void Type::add_oneofs(std::string&& value) {
  _impl_.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);  _impl_.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) {
  _impl_.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 _impl_.oneofs_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
Type::mutable_oneofs() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs)
  return &_impl_.oneofs_;
}

// repeated .google.protobuf.Option options = 4;
inline int Type::_internal_options_size() const {
  return _impl_.options_.size();
}
inline int Type::options_size() const {
  return _internal_options_size();
}
inline void Type::clear_options() {
  _impl_.options_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Type::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options)
  return _impl_.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 &_impl_.options_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Type::_internal_options(int index) const {
  return _impl_.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 _impl_.options_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Type::add_options() {
  ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
  // @@protoc_insertion_point(field_add:google.protobuf.Type.options)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
Type::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
  return _impl_.options_;
}

// .google.protobuf.SourceContext source_context = 5;
inline bool Type::_internal_has_source_context() const {
  return this != internal_default_instance() && _impl_.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 = _impl_.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 (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_);
  }
  _impl_.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() {
  
  ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  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 = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::_internal_mutable_source_context() {
  
  if (_impl_.source_context_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
    _impl_.source_context_ = p;
  }
  return _impl_.source_context_;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Type::mutable_source_context() {
  ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context)
  return _msg;
}
inline void Type::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_);
  }
  if (source_context) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
                reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context));
    if (message_arena != submessage_arena) {
      source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, source_context, submessage_arena);
    }

  } else {

  }
  _impl_.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() {
  _impl_.syntax_ = 0;
}
inline ::PROTOBUF_NAMESPACE_ID::Syntax Type::_internal_syntax() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.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) {
  
  _impl_.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() {
  _impl_.kind_ = 0;
}
inline ::PROTOBUF_NAMESPACE_ID::Field_Kind Field::_internal_kind() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Kind >(_impl_.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) {
  
  _impl_.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() {
  _impl_.cardinality_ = 0;
}
inline ::PROTOBUF_NAMESPACE_ID::Field_Cardinality Field::_internal_cardinality() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::Field_Cardinality >(_impl_.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) {
  
  _impl_.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() {
  _impl_.number_ = 0;
}
inline int32_t Field::_internal_number() const {
  return _impl_.number_;
}
inline int32_t Field::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.number)
  return _internal_number();
}
inline void Field::_internal_set_number(int32_t value) {

  _impl_.number_ = value;
}
inline void Field::set_number(int32_t value) {
  _internal_set_number(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Field.number)
}

// string name = 4;
inline void Field::clear_name() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Field::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Field::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.name)
}
inline std::string* Field::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name)
  return _s;
}
inline const std::string& Field::_internal_name() const {
  return _impl_.name_.Get();
}
inline void Field::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Field::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Field::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
  return _impl_.name_.Release();
}
inline void Field::set_allocated_name(std::string* name) {
  if (name != nullptr) {

  } else {

  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name)
}

// string type_url = 6;
inline void Field::clear_type_url() {
  _impl_.type_url_.ClearToEmpty();
}
inline const std::string& Field::type_url() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url)
  return _internal_type_url();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Field::set_type_url(ArgT0&& arg0, ArgT... args) {
 
 _impl_.type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
}
inline std::string* Field::mutable_type_url() {
  std::string* _s = _internal_mutable_type_url();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url)
  return _s;
}
inline const std::string& Field::_internal_type_url() const {
  return _impl_.type_url_.Get();
}
inline void Field::_internal_set_type_url(const std::string& value) {

  _impl_.type_url_.Set(value, GetArenaForAllocation());
}
inline std::string* Field::_internal_mutable_type_url() {

  return _impl_.type_url_.Mutable(GetArenaForAllocation());
}
inline std::string* Field::release_type_url() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
  return _impl_.type_url_.Release();
}
inline void Field::set_allocated_type_url(std::string* type_url) {
  if (type_url != nullptr) {

  } else {

  }
  _impl_.type_url_.SetAllocated(type_url, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.type_url_.IsDefault()) {
    _impl_.type_url_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url)
}

// int32 oneof_index = 7;
inline void Field::clear_oneof_index() {
  _impl_.oneof_index_ = 0;
}
inline int32_t Field::_internal_oneof_index() const {
  return _impl_.oneof_index_;
}
inline int32_t 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(int32_t value) {

  _impl_.oneof_index_ = value;
}
inline void Field::set_oneof_index(int32_t value) {
  _internal_set_oneof_index(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index)
}

// bool packed = 8;
inline void Field::clear_packed() {
  _impl_.packed_ = false;
}
inline bool Field::_internal_packed() const {
  return _impl_.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) {

  _impl_.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 _impl_.options_.size();
}
inline int Field::options_size() const {
  return _internal_options_size();
}
inline void Field::clear_options() {
  _impl_.options_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Field::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options)
  return _impl_.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 &_impl_.options_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Field::_internal_options(int index) const {
  return _impl_.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 _impl_.options_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Field::add_options() {
  ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
  // @@protoc_insertion_point(field_add:google.protobuf.Field.options)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
Field::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Field.options)
  return _impl_.options_;
}

// string json_name = 10;
inline void Field::clear_json_name() {
  _impl_.json_name_.ClearToEmpty();
}
inline const std::string& Field::json_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
  return _internal_json_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Field::set_json_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.json_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
}
inline std::string* Field::mutable_json_name() {
  std::string* _s = _internal_mutable_json_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
  return _s;
}
inline const std::string& Field::_internal_json_name() const {
  return _impl_.json_name_.Get();
}
inline void Field::_internal_set_json_name(const std::string& value) {

  _impl_.json_name_.Set(value, GetArenaForAllocation());
}
inline std::string* Field::_internal_mutable_json_name() {

  return _impl_.json_name_.Mutable(GetArenaForAllocation());
}
inline std::string* Field::release_json_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
  return _impl_.json_name_.Release();
}
inline void Field::set_allocated_json_name(std::string* json_name) {
  if (json_name != nullptr) {

  } else {

  }
  _impl_.json_name_.SetAllocated(json_name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.json_name_.IsDefault()) {
    _impl_.json_name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}

// string default_value = 11;
inline void Field::clear_default_value() {
  _impl_.default_value_.ClearToEmpty();
}
inline const std::string& Field::default_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value)
  return _internal_default_value();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Field::set_default_value(ArgT0&& arg0, ArgT... args) {
 
 _impl_.default_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
}
inline std::string* Field::mutable_default_value() {
  std::string* _s = _internal_mutable_default_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value)
  return _s;
}
inline const std::string& Field::_internal_default_value() const {
  return _impl_.default_value_.Get();
}
inline void Field::_internal_set_default_value(const std::string& value) {

  _impl_.default_value_.Set(value, GetArenaForAllocation());
}
inline std::string* Field::_internal_mutable_default_value() {

  return _impl_.default_value_.Mutable(GetArenaForAllocation());
}
inline std::string* Field::release_default_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
  return _impl_.default_value_.Release();
}
inline void Field::set_allocated_default_value(std::string* default_value) {
  if (default_value != nullptr) {

  } else {

  }
  _impl_.default_value_.SetAllocated(default_value, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.default_value_.IsDefault()) {
    _impl_.default_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value)
}

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

// Enum

// string name = 1;
inline void Enum::clear_name() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Enum::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Enum::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Enum.name)
}
inline std::string* Enum::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name)
  return _s;
}
inline const std::string& Enum::_internal_name() const {
  return _impl_.name_.Get();
}
inline void Enum::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Enum::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Enum::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
  return _impl_.name_.Release();
}
inline void Enum::set_allocated_name(std::string* name) {
  if (name != nullptr) {

  } else {

  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name)
}

// repeated .google.protobuf.EnumValue enumvalue = 2;
inline int Enum::_internal_enumvalue_size() const {
  return _impl_.enumvalue_.size();
}
inline int Enum::enumvalue_size() const {
  return _internal_enumvalue_size();
}
inline void Enum::clear_enumvalue() {
  _impl_.enumvalue_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::mutable_enumvalue(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue)
  return _impl_.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 &_impl_.enumvalue_;
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumValue& Enum::_internal_enumvalue(int index) const {
  return _impl_.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 _impl_.enumvalue_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::EnumValue* Enum::add_enumvalue() {
  ::PROTOBUF_NAMESPACE_ID::EnumValue* _add = _internal_add_enumvalue();
  // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValue >&
Enum::enumvalue() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
  return _impl_.enumvalue_;
}

// repeated .google.protobuf.Option options = 3;
inline int Enum::_internal_options_size() const {
  return _impl_.options_.size();
}
inline int Enum::options_size() const {
  return _internal_options_size();
}
inline void Enum::clear_options() {
  _impl_.options_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options)
  return _impl_.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 &_impl_.options_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Enum::_internal_options(int index) const {
  return _impl_.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 _impl_.options_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Enum::add_options() {
  ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
  // @@protoc_insertion_point(field_add:google.protobuf.Enum.options)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
Enum::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
  return _impl_.options_;
}

// .google.protobuf.SourceContext source_context = 4;
inline bool Enum::_internal_has_source_context() const {
  return this != internal_default_instance() && _impl_.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 = _impl_.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 (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_);
  }
  _impl_.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() {
  
  ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  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 = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::_internal_mutable_source_context() {
  
  if (_impl_.source_context_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
    _impl_.source_context_ = p;
  }
  return _impl_.source_context_;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Enum::mutable_source_context() {
  ::PROTOBUF_NAMESPACE_ID::SourceContext* _msg = _internal_mutable_source_context();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context)
  return _msg;
}
inline void Enum::set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_);
  }
  if (source_context) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
                reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context));
    if (message_arena != submessage_arena) {
      source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, source_context, submessage_arena);
    }

  } else {

  }
  _impl_.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() {
  _impl_.syntax_ = 0;
}
inline ::PROTOBUF_NAMESPACE_ID::Syntax Enum::_internal_syntax() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.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) {
  
  _impl_.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() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& EnumValue::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void EnumValue::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name)
}
inline std::string* EnumValue::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name)
  return _s;
}
inline const std::string& EnumValue::_internal_name() const {
  return _impl_.name_.Get();
}
inline void EnumValue::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* EnumValue::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* EnumValue::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
  return _impl_.name_.Release();
}
inline void EnumValue::set_allocated_name(std::string* name) {
  if (name != nullptr) {

  } else {

  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name)
}

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

  _impl_.number_ = value;
}
inline void EnumValue::set_number(int32_t 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 _impl_.options_.size();
}
inline int EnumValue::options_size() const {
  return _internal_options_size();
}
inline void EnumValue::clear_options() {
  _impl_.options_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options)
  return _impl_.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 &_impl_.options_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& EnumValue::_internal_options(int index) const {
  return _impl_.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 _impl_.options_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* EnumValue::add_options() {
  ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
  // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
EnumValue::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
  return _impl_.options_;
}

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

// Option

// string name = 1;
inline void Option::clear_name() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Option::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Option.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Option::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Option.name)
}
inline std::string* Option::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name)
  return _s;
}
inline const std::string& Option::_internal_name() const {
  return _impl_.name_.Get();
}
inline void Option::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Option::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Option::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
  return _impl_.name_.Release();
}
inline void Option::set_allocated_name(std::string* name) {
  if (name != nullptr) {

  } else {

  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name)
}

// .google.protobuf.Any value = 2;
inline bool Option::_internal_has_value() const {
  return this != internal_default_instance() && _impl_.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 = _impl_.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 (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.value_);
  }
  _impl_.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() {
  
  ::PROTOBUF_NAMESPACE_ID::Any* temp = _impl_.value_;
  _impl_.value_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  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 = _impl_.value_;
  _impl_.value_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::Any* Option::_internal_mutable_value() {
  
  if (_impl_.value_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Any>(GetArenaForAllocation());
    _impl_.value_ = p;
  }
  return _impl_.value_;
}
inline ::PROTOBUF_NAMESPACE_ID::Any* Option::mutable_value() {
  ::PROTOBUF_NAMESPACE_ID::Any* _msg = _internal_mutable_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value)
  return _msg;
}
inline void Option::set_allocated_value(::PROTOBUF_NAMESPACE_ID::Any* value) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.value_);
  }
  if (value) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
                reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value));
    if (message_arena != submessage_arena) {
      value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, value, submessage_arena);
    }

  } else {

  }
  _impl_.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_2fprotobuf_2ftype_2eproto_2epb_2eh
