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

#ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
#define PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto

#include <string>

#include <google/protobuf/stubs/common.h>

#if GOOGLE_PROTOBUF_VERSION < 3006001
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please update
#error your headers.
#endif
#if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/metadata.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)
#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto LIBPROTOBUF_EXPORT

namespace protobuf_google_2fprotobuf_2ftype_2eproto {
// Internal implementation detail -- do not use these members.
struct LIBPROTOBUF_EXPORT TableStruct {
  static const ::google::protobuf::internal::ParseTableField entries[];
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
  static const ::google::protobuf::internal::ParseTable schema[5];
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void LIBPROTOBUF_EXPORT AddDescriptors();
}  // namespace protobuf_google_2fprotobuf_2ftype_2eproto
namespace google {
namespace protobuf {
class Enum;
class EnumDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern EnumDefaultTypeInternal _Enum_default_instance_;
class EnumValue;
class EnumValueDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern EnumValueDefaultTypeInternal _EnumValue_default_instance_;
class Field;
class FieldDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern FieldDefaultTypeInternal _Field_default_instance_;
class Option;
class OptionDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern OptionDefaultTypeInternal _Option_default_instance_;
class Type;
class TypeDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern TypeDefaultTypeInternal _Type_default_instance_;
}  // namespace protobuf
}  // namespace google
namespace google {
namespace protobuf {
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Enum* Arena::CreateMaybeMessage<::google::protobuf::Enum>(Arena*);
template<> LIBPROTOBUF_EXPORT ::google::protobuf::EnumValue* Arena::CreateMaybeMessage<::google::protobuf::EnumValue>(Arena*);
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Field* Arena::CreateMaybeMessage<::google::protobuf::Field>(Arena*);
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Option* Arena::CreateMaybeMessage<::google::protobuf::Option>(Arena*);
template<> LIBPROTOBUF_EXPORT ::google::protobuf::Type* Arena::CreateMaybeMessage<::google::protobuf::Type>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace google {
namespace protobuf {

enum Field_Kind {
  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_ = ::google::protobuf::kint32min,
  Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
};
LIBPROTOBUF_EXPORT bool Field_Kind_IsValid(int value);
const Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN;
const Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64;
const int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor();
inline const ::std::string& Field_Kind_Name(Field_Kind value) {
  return ::google::protobuf::internal::NameOfEnum(
    Field_Kind_descriptor(), value);
}
inline bool Field_Kind_Parse(
    const ::std::string& name, Field_Kind* value) {
  return ::google::protobuf::internal::ParseNamedEnum<Field_Kind>(
    Field_Kind_descriptor(), name, value);
}
enum Field_Cardinality {
  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_ = ::google::protobuf::kint32min,
  Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
};
LIBPROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value);
const Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN;
const Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED;
const int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor();
inline const ::std::string& Field_Cardinality_Name(Field_Cardinality value) {
  return ::google::protobuf::internal::NameOfEnum(
    Field_Cardinality_descriptor(), value);
}
inline bool Field_Cardinality_Parse(
    const ::std::string& name, Field_Cardinality* value) {
  return ::google::protobuf::internal::ParseNamedEnum<Field_Cardinality>(
    Field_Cardinality_descriptor(), name, value);
}
enum Syntax {
  SYNTAX_PROTO2 = 0,
  SYNTAX_PROTO3 = 1,
  Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
  Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
};
LIBPROTOBUF_EXPORT bool Syntax_IsValid(int value);
const Syntax Syntax_MIN = SYNTAX_PROTO2;
const Syntax Syntax_MAX = SYNTAX_PROTO3;
const int Syntax_ARRAYSIZE = Syntax_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Syntax_descriptor();
inline const ::std::string& Syntax_Name(Syntax value) {
  return ::google::protobuf::internal::NameOfEnum(
    Syntax_descriptor(), value);
}
inline bool Syntax_Parse(
    const ::std::string& name, Syntax* value) {
  return ::google::protobuf::internal::ParseNamedEnum<Syntax>(
    Syntax_descriptor(), name, value);
}
// ===================================================================

class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ {
 public:
  Type();
  virtual ~Type();

  Type(const Type& from);

  inline Type& operator=(const Type& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Type(Type&& from) noexcept
    : Type() {
    *this = ::std::move(from);
  }

  inline Type& operator=(Type&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline ::google::protobuf::Arena* GetArena() const final {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const final {
    return MaybeArenaPtr();
  }
  static const ::google::protobuf::Descriptor* descriptor();
  static const Type& default_instance();

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

  void UnsafeArenaSwap(Type* other);
  void Swap(Type* other);
  friend void swap(Type& a, Type& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Type* other);
  protected:
  explicit Type(::google::protobuf::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .google.protobuf.Field fields = 2;
  int fields_size() const;
  void clear_fields();
  static const int kFieldsFieldNumber = 2;
  ::google::protobuf::Field* mutable_fields(int index);
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
      mutable_fields();
  const ::google::protobuf::Field& fields(int index) const;
  ::google::protobuf::Field* add_fields();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
      fields() const;

  // repeated string oneofs = 3;
  int oneofs_size() const;
  void clear_oneofs();
  static const int kOneofsFieldNumber = 3;
  const ::std::string& oneofs(int index) const;
  ::std::string* mutable_oneofs(int index);
  void set_oneofs(int index, const ::std::string& value);
  #if LANG_CXX11
  void set_oneofs(int index, ::std::string&& value);
  #endif
  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);
  #if LANG_CXX11
  void add_oneofs(::std::string&& value);
  #endif
  void add_oneofs(const char* value);
  void add_oneofs(const char* value, size_t size);
  const ::google::protobuf::RepeatedPtrField< ::std::string>& oneofs() const;
  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_oneofs();

  // repeated .google.protobuf.Option options = 4;
  int options_size() const;
  void clear_options();
  static const int kOptionsFieldNumber = 4;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_options();
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* add_options();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_name();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      ::std::string* name);

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

  // .google.protobuf.Syntax syntax = 6;
  void clear_syntax();
  static const int kSyntaxFieldNumber = 6;
  ::google::protobuf::Syntax syntax() const;
  void set_syntax(::google::protobuf::Syntax value);

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

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

class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ {
 public:
  Field();
  virtual ~Field();

  Field(const Field& from);

  inline Field& operator=(const Field& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Field(Field&& from) noexcept
    : Field() {
    *this = ::std::move(from);
  }

  inline Field& operator=(Field&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline ::google::protobuf::Arena* GetArena() const final {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const final {
    return MaybeArenaPtr();
  }
  static const ::google::protobuf::Descriptor* descriptor();
  static const Field& default_instance();

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

  void UnsafeArenaSwap(Field* other);
  void Swap(Field* other);
  friend void swap(Field& a, Field& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Field* other);
  protected:
  explicit Field(::google::protobuf::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

  typedef Field_Kind Kind;
  static const Kind TYPE_UNKNOWN =
    Field_Kind_TYPE_UNKNOWN;
  static const Kind TYPE_DOUBLE =
    Field_Kind_TYPE_DOUBLE;
  static const Kind TYPE_FLOAT =
    Field_Kind_TYPE_FLOAT;
  static const Kind TYPE_INT64 =
    Field_Kind_TYPE_INT64;
  static const Kind TYPE_UINT64 =
    Field_Kind_TYPE_UINT64;
  static const Kind TYPE_INT32 =
    Field_Kind_TYPE_INT32;
  static const Kind TYPE_FIXED64 =
    Field_Kind_TYPE_FIXED64;
  static const Kind TYPE_FIXED32 =
    Field_Kind_TYPE_FIXED32;
  static const Kind TYPE_BOOL =
    Field_Kind_TYPE_BOOL;
  static const Kind TYPE_STRING =
    Field_Kind_TYPE_STRING;
  static const Kind TYPE_GROUP =
    Field_Kind_TYPE_GROUP;
  static const Kind TYPE_MESSAGE =
    Field_Kind_TYPE_MESSAGE;
  static const Kind TYPE_BYTES =
    Field_Kind_TYPE_BYTES;
  static const Kind TYPE_UINT32 =
    Field_Kind_TYPE_UINT32;
  static const Kind TYPE_ENUM =
    Field_Kind_TYPE_ENUM;
  static const Kind TYPE_SFIXED32 =
    Field_Kind_TYPE_SFIXED32;
  static const Kind TYPE_SFIXED64 =
    Field_Kind_TYPE_SFIXED64;
  static const Kind TYPE_SINT32 =
    Field_Kind_TYPE_SINT32;
  static const Kind TYPE_SINT64 =
    Field_Kind_TYPE_SINT64;
  static inline bool Kind_IsValid(int value) {
    return Field_Kind_IsValid(value);
  }
  static const Kind Kind_MIN =
    Field_Kind_Kind_MIN;
  static const Kind Kind_MAX =
    Field_Kind_Kind_MAX;
  static const int Kind_ARRAYSIZE =
    Field_Kind_Kind_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Kind_descriptor() {
    return Field_Kind_descriptor();
  }
  static inline const ::std::string& Kind_Name(Kind value) {
    return Field_Kind_Name(value);
  }
  static inline bool Kind_Parse(const ::std::string& name,
      Kind* value) {
    return Field_Kind_Parse(name, value);
  }

  typedef Field_Cardinality Cardinality;
  static const Cardinality CARDINALITY_UNKNOWN =
    Field_Cardinality_CARDINALITY_UNKNOWN;
  static const Cardinality CARDINALITY_OPTIONAL =
    Field_Cardinality_CARDINALITY_OPTIONAL;
  static const Cardinality CARDINALITY_REQUIRED =
    Field_Cardinality_CARDINALITY_REQUIRED;
  static const Cardinality CARDINALITY_REPEATED =
    Field_Cardinality_CARDINALITY_REPEATED;
  static inline bool Cardinality_IsValid(int value) {
    return Field_Cardinality_IsValid(value);
  }
  static const Cardinality Cardinality_MIN =
    Field_Cardinality_Cardinality_MIN;
  static const Cardinality Cardinality_MAX =
    Field_Cardinality_Cardinality_MAX;
  static const int Cardinality_ARRAYSIZE =
    Field_Cardinality_Cardinality_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Cardinality_descriptor() {
    return Field_Cardinality_descriptor();
  }
  static inline const ::std::string& Cardinality_Name(Cardinality value) {
    return Field_Cardinality_Name(value);
  }
  static inline bool Cardinality_Parse(const ::std::string& name,
      Cardinality* value) {
    return Field_Cardinality_Parse(name, value);
  }

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

  // repeated .google.protobuf.Option options = 9;
  int options_size() const;
  void clear_options();
  static const int kOptionsFieldNumber = 9;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_options();
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* add_options();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
      options() const;

  // string name = 4;
  void clear_name();
  static const int kNameFieldNumber = 4;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_name();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      ::std::string* name);

  // string type_url = 6;
  void clear_type_url();
  static const int kTypeUrlFieldNumber = 6;
  const ::std::string& type_url() const;
  void set_type_url(const ::std::string& value);
  #if LANG_CXX11
  void set_type_url(::std::string&& value);
  #endif
  void set_type_url(const char* value);
  void set_type_url(const char* value, size_t size);
  ::std::string* mutable_type_url();
  ::std::string* release_type_url();
  void set_allocated_type_url(::std::string* type_url);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_type_url();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_type_url(
      ::std::string* type_url);

  // string json_name = 10;
  void clear_json_name();
  static const int kJsonNameFieldNumber = 10;
  const ::std::string& json_name() const;
  void set_json_name(const ::std::string& value);
  #if LANG_CXX11
  void set_json_name(::std::string&& value);
  #endif
  void set_json_name(const char* value);
  void set_json_name(const char* value, size_t size);
  ::std::string* mutable_json_name();
  ::std::string* release_json_name();
  void set_allocated_json_name(::std::string* json_name);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_json_name();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_json_name(
      ::std::string* json_name);

  // string default_value = 11;
  void clear_default_value();
  static const int kDefaultValueFieldNumber = 11;
  const ::std::string& default_value() const;
  void set_default_value(const ::std::string& value);
  #if LANG_CXX11
  void set_default_value(::std::string&& value);
  #endif
  void set_default_value(const char* value);
  void set_default_value(const char* value, size_t size);
  ::std::string* mutable_default_value();
  ::std::string* release_default_value();
  void set_allocated_default_value(::std::string* default_value);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_default_value();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_default_value(
      ::std::string* default_value);

  // .google.protobuf.Field.Kind kind = 1;
  void clear_kind();
  static const int kKindFieldNumber = 1;
  ::google::protobuf::Field_Kind kind() const;
  void set_kind(::google::protobuf::Field_Kind value);

  // .google.protobuf.Field.Cardinality cardinality = 2;
  void clear_cardinality();
  static const int kCardinalityFieldNumber = 2;
  ::google::protobuf::Field_Cardinality cardinality() const;
  void set_cardinality(::google::protobuf::Field_Cardinality value);

  // int32 number = 3;
  void clear_number();
  static const int kNumberFieldNumber = 3;
  ::google::protobuf::int32 number() const;
  void set_number(::google::protobuf::int32 value);

  // int32 oneof_index = 7;
  void clear_oneof_index();
  static const int kOneofIndexFieldNumber = 7;
  ::google::protobuf::int32 oneof_index() const;
  void set_oneof_index(::google::protobuf::int32 value);

  // bool packed = 8;
  void clear_packed();
  static const int kPackedFieldNumber = 8;
  bool packed() const;
  void set_packed(bool value);

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

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

class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ {
 public:
  Enum();
  virtual ~Enum();

  Enum(const Enum& from);

  inline Enum& operator=(const Enum& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Enum(Enum&& from) noexcept
    : Enum() {
    *this = ::std::move(from);
  }

  inline Enum& operator=(Enum&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline ::google::protobuf::Arena* GetArena() const final {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const final {
    return MaybeArenaPtr();
  }
  static const ::google::protobuf::Descriptor* descriptor();
  static const Enum& default_instance();

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

  void UnsafeArenaSwap(Enum* other);
  void Swap(Enum* other);
  friend void swap(Enum& a, Enum& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Enum* other);
  protected:
  explicit Enum(::google::protobuf::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .google.protobuf.EnumValue enumvalue = 2;
  int enumvalue_size() const;
  void clear_enumvalue();
  static const int kEnumvalueFieldNumber = 2;
  ::google::protobuf::EnumValue* mutable_enumvalue(int index);
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
      mutable_enumvalue();
  const ::google::protobuf::EnumValue& enumvalue(int index) const;
  ::google::protobuf::EnumValue* add_enumvalue();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
      enumvalue() const;

  // repeated .google.protobuf.Option options = 3;
  int options_size() const;
  void clear_options();
  static const int kOptionsFieldNumber = 3;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_options();
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* add_options();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_name();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      ::std::string* name);

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

  // .google.protobuf.Syntax syntax = 5;
  void clear_syntax();
  static const int kSyntaxFieldNumber = 5;
  ::google::protobuf::Syntax syntax() const;
  void set_syntax(::google::protobuf::Syntax value);

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

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

class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ {
 public:
  EnumValue();
  virtual ~EnumValue();

  EnumValue(const EnumValue& from);

  inline EnumValue& operator=(const EnumValue& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  EnumValue(EnumValue&& from) noexcept
    : EnumValue() {
    *this = ::std::move(from);
  }

  inline EnumValue& operator=(EnumValue&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline ::google::protobuf::Arena* GetArena() const final {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const final {
    return MaybeArenaPtr();
  }
  static const ::google::protobuf::Descriptor* descriptor();
  static const EnumValue& default_instance();

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

  void UnsafeArenaSwap(EnumValue* other);
  void Swap(EnumValue* other);
  friend void swap(EnumValue& a, EnumValue& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumValue* other);
  protected:
  explicit EnumValue(::google::protobuf::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // repeated .google.protobuf.Option options = 3;
  int options_size() const;
  void clear_options();
  static const int kOptionsFieldNumber = 3;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_options();
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* add_options();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_name();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      ::std::string* name);

  // int32 number = 2;
  void clear_number();
  static const int kNumberFieldNumber = 2;
  ::google::protobuf::int32 number() const;
  void set_number(::google::protobuf::int32 value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::int32 number_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ {
 public:
  Option();
  virtual ~Option();

  Option(const Option& from);

  inline Option& operator=(const Option& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Option(Option&& from) noexcept
    : Option() {
    *this = ::std::move(from);
  }

  inline Option& operator=(Option&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  inline ::google::protobuf::Arena* GetArena() const final {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const final {
    return MaybeArenaPtr();
  }
  static const ::google::protobuf::Descriptor* descriptor();
  static const Option& default_instance();

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

  void UnsafeArenaSwap(Option* other);
  void Swap(Option* other);
  friend void swap(Option& a, Option& b) {
    a.Swap(&b);
  }

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

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

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Option* other);
  protected:
  explicit Option(::google::protobuf::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  ::std::string* unsafe_arena_release_name();
  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
  "    string fields are deprecated and will be removed in a"
  "    future release.")
  void unsafe_arena_set_allocated_name(
      ::std::string* name);

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::Any* value_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
};
// ===================================================================


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

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

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

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

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

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

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

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

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

// Field

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

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

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

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

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

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

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

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

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

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

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

// Enum

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

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

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

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

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

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

// EnumValue

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

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

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

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

// Option

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

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

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

namespace google {
namespace protobuf {

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

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
