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

#ifndef PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED

#include <string>

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

#if GOOGLE_PROTOBUF_VERSION < 3005000
#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 3005001 < 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/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)

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();
void LIBPROTOBUF_EXPORT InitDefaultsTypeImpl();
void LIBPROTOBUF_EXPORT InitDefaultsType();
void LIBPROTOBUF_EXPORT InitDefaultsFieldImpl();
void LIBPROTOBUF_EXPORT InitDefaultsField();
void LIBPROTOBUF_EXPORT InitDefaultsEnumImpl();
void LIBPROTOBUF_EXPORT InitDefaultsEnum();
void LIBPROTOBUF_EXPORT InitDefaultsEnumValueImpl();
void LIBPROTOBUF_EXPORT InitDefaultsEnumValue();
void LIBPROTOBUF_EXPORT InitDefaultsOptionImpl();
void LIBPROTOBUF_EXPORT InitDefaultsOption();
inline void LIBPROTOBUF_EXPORT InitDefaults() {
  InitDefaultsType();
  InitDefaultsField();
  InitDefaultsEnum();
  InitDefaultsEnumValue();
  InitDefaultsOption();
}
}  // 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 {

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 PROTOBUF_FINAL {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const PROTOBUF_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 PROTOBUF_CONSTEXPR int const 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 PROTOBUF_FINAL { return New(NULL); }

  Type* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const Type& from);
  void MergeFrom(const Type& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_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 PROTOBUF_FINAL;

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

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

  // repeated .google.protobuf.Field fields = 2;
  int fields_size() const;
  void clear_fields();
  static const int kFieldsFieldNumber = 2;
  const ::google::protobuf::Field& fields(int index) const;
  ::google::protobuf::Field* mutable_fields(int index);
  ::google::protobuf::Field* add_fields();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
      mutable_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;
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::Option* add_options();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_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:
  void _slow_mutable_source_context();
  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 int _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
  friend void ::protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsTypeImpl();
};
// -------------------------------------------------------------------

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 PROTOBUF_FINAL {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const PROTOBUF_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 PROTOBUF_CONSTEXPR int const 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 PROTOBUF_FINAL { return New(NULL); }

  Field* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const Field& from);
  void MergeFrom(const Field& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_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 PROTOBUF_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;
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::Option* add_options();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_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 int _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
  friend void ::protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsFieldImpl();
};
// -------------------------------------------------------------------

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 PROTOBUF_FINAL {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const PROTOBUF_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 PROTOBUF_CONSTEXPR int const 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 PROTOBUF_FINAL { return New(NULL); }

  Enum* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const Enum& from);
  void MergeFrom(const Enum& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_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 PROTOBUF_FINAL;

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

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

  // repeated .google.protobuf.EnumValue enumvalue = 2;
  int enumvalue_size() const;
  void clear_enumvalue();
  static const int kEnumvalueFieldNumber = 2;
  const ::google::protobuf::EnumValue& enumvalue(int index) const;
  ::google::protobuf::EnumValue* mutable_enumvalue(int index);
  ::google::protobuf::EnumValue* add_enumvalue();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
      mutable_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;
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::Option* add_options();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_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:
  void _slow_mutable_source_context();
  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 int _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
  friend void ::protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsEnumImpl();
};
// -------------------------------------------------------------------

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 PROTOBUF_FINAL {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const PROTOBUF_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 PROTOBUF_CONSTEXPR int const 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 PROTOBUF_FINAL { return New(NULL); }

  EnumValue* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const EnumValue& from);
  void MergeFrom(const EnumValue& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_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 PROTOBUF_FINAL;

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

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

  // repeated .google.protobuf.Option options = 3;
  int options_size() const;
  void clear_options();
  static const int kOptionsFieldNumber = 3;
  const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* mutable_options(int index);
  ::google::protobuf::Option* add_options();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
      mutable_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 int _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
  friend void ::protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsEnumValueImpl();
};
// -------------------------------------------------------------------

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 PROTOBUF_FINAL {
    return GetArenaNoVirtual();
  }
  inline void* GetMaybeArenaPointer() const PROTOBUF_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 PROTOBUF_CONSTEXPR int const 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 PROTOBUF_FINAL { return New(NULL); }

  Option* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const Option& from);
  void MergeFrom(const Option& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_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 PROTOBUF_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:
  void _slow_mutable_value();
  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 int _cached_size_;
  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
  friend void ::protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaultsOptionImpl();
};
// ===================================================================


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

#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 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::mutable_fields(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields)
  return fields_.Mutable(index);
}
inline ::google::protobuf::Field* Type::add_fields() {
  // @@protoc_insertion_point(field_add:google.protobuf.Type.fields)
  return fields_.Add();
}
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::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 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::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options)
  return options_.Mutable(index);
}
inline ::google::protobuf::Option* Type::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.Type.options)
  return options_.Add();
}
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::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::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, NULL);
  }
  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) {
    _slow_mutable_source_context();
  }
  // @@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 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::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options)
  return options_.Mutable(index);
}
inline ::google::protobuf::Option* Field::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.Field.options)
  return options_.Add();
}
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::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 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::mutable_enumvalue(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue)
  return enumvalue_.Mutable(index);
}
inline ::google::protobuf::EnumValue* Enum::add_enumvalue() {
  // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue)
  return enumvalue_.Add();
}
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::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 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::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options)
  return options_.Mutable(index);
}
inline ::google::protobuf::Option* Enum::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.Enum.options)
  return options_.Add();
}
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::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::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, NULL);
  }
  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) {
    _slow_mutable_source_context();
  }
  // @@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 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::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options)
  return options_.Mutable(index);
}
inline ::google::protobuf::Option* EnumValue::add_options() {
  // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options)
  return options_.Add();
}
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::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::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, NULL);
  }
  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) {
    _slow_mutable_value();
  }
  // @@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> : ::google::protobuf::internal::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> : ::google::protobuf::internal::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> : ::google::protobuf::internal::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_google_2fprotobuf_2ftype_2eproto__INCLUDED
