// 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 < 3000000
#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 3000000 < 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/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#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 google {
namespace protobuf {

// Internal implementation detail -- do not call these.
void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();

class Enum;
class EnumValue;
class Field;
class Option;
class Type;

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 {
 public:
  Type();
  virtual ~Type();

  Type(const Type& from);

  inline Type& operator=(const Type& from) {
    CopyFrom(from);
    return *this;
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const Type& default_instance();

  void Swap(Type* other);

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

  inline Type* New() const { return New(NULL); }

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(Type* other);
  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;

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

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

  // optional string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // 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);
  void set_oneofs(int index, const char* value);
  void set_oneofs(int index, const char* value, size_t size);
  ::std::string* add_oneofs();
  void add_oneofs(const ::std::string& value);
  void add_oneofs(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;

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

  // optional .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_;
  bool _is_default_instance_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field > fields_;
  ::google::protobuf::RepeatedPtrField< ::std::string> oneofs_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
  ::google::protobuf::SourceContext* source_context_;
  int syntax_;
  mutable int _cached_size_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();

  void InitAsDefaultInstance();
  static Type* default_instance_;
};
// -------------------------------------------------------------------

class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
 public:
  Field();
  virtual ~Field();

  Field(const Field& from);

  inline Field& operator=(const Field& from) {
    CopyFrom(from);
    return *this;
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const Field& default_instance();

  void Swap(Field* other);

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

  inline Field* New() const { return New(NULL); }

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(Field* other);
  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;

  // 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 -------------------------------------------------------

  // optional .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);

  // optional .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);

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

  // optional string name = 4;
  void clear_name();
  static const int kNameFieldNumber = 4;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // optional 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);
  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);

  // optional 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);

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

  // 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;

  // optional 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);
  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);

  // optional 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);
  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);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  bool _is_default_instance_;
  int kind_;
  int cardinality_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::int32 number_;
  ::google::protobuf::int32 oneof_index_;
  ::google::protobuf::internal::ArenaStringPtr type_url_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
  ::google::protobuf::internal::ArenaStringPtr json_name_;
  ::google::protobuf::internal::ArenaStringPtr default_value_;
  bool packed_;
  mutable int _cached_size_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();

  void InitAsDefaultInstance();
  static Field* default_instance_;
};
// -------------------------------------------------------------------

class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
 public:
  Enum();
  virtual ~Enum();

  Enum(const Enum& from);

  inline Enum& operator=(const Enum& from) {
    CopyFrom(from);
    return *this;
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const Enum& default_instance();

  void Swap(Enum* other);

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

  inline Enum* New() const { return New(NULL); }

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(Enum* other);
  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;

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

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

  // optional string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // 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;

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

  // optional .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_;
  bool _is_default_instance_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
  ::google::protobuf::SourceContext* source_context_;
  int syntax_;
  mutable int _cached_size_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();

  void InitAsDefaultInstance();
  static Enum* default_instance_;
};
// -------------------------------------------------------------------

class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message {
 public:
  EnumValue();
  virtual ~EnumValue();

  EnumValue(const EnumValue& from);

  inline EnumValue& operator=(const EnumValue& from) {
    CopyFrom(from);
    return *this;
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const EnumValue& default_instance();

  void Swap(EnumValue* other);

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

  inline EnumValue* New() const { return New(NULL); }

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(EnumValue* other);
  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;

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

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

  // optional string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

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

  // 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;

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  bool _is_default_instance_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
  ::google::protobuf::int32 number_;
  mutable int _cached_size_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();

  void InitAsDefaultInstance();
  static EnumValue* default_instance_;
};
// -------------------------------------------------------------------

class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message {
 public:
  Option();
  virtual ~Option();

  Option(const Option& from);

  inline Option& operator=(const Option& from) {
    CopyFrom(from);
    return *this;
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const Option& default_instance();

  void Swap(Option* other);

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

  inline Option* New() const { return New(NULL); }

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(Option* other);
  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;

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

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

  // optional string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  bool _is_default_instance_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::Any* value_;
  mutable int _cached_size_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();

  void InitAsDefaultInstance();
  static Option* default_instance_;
};
// ===================================================================


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

#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// Type

// optional string name = 1;
inline void Type::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Type::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.name)
  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Type::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Type.name)
}
inline void Type::set_name(const char* value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name)
}
inline void Type::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Type::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Type::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_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);
}
inline void Type::set_oneofs(int index, const char* value) {
  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)
}
inline void Type::add_oneofs(const char* value) {
  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_;
}

// optional .google.protobuf.SourceContext source_context = 5;
inline bool Type::has_source_context() const {
  return !_is_default_instance_ && source_context_ != NULL;
}
inline void Type::clear_source_context() {
  if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
  source_context_ = NULL;
}
inline const ::google::protobuf::SourceContext& Type::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
  return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_;
}
inline ::google::protobuf::SourceContext* Type::mutable_source_context() {
  
  if (source_context_ == NULL) {
    source_context_ = new ::google::protobuf::SourceContext;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context)
  return source_context_;
}
inline ::google::protobuf::SourceContext* Type::release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context)
  
  ::google::protobuf::SourceContext* temp = source_context_;
  source_context_ = NULL;
  return temp;
}
inline void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
  delete source_context_;
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
}

// optional .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

// optional .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)
}

// optional .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)
}

// optional 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)
}

// optional string name = 4;
inline void Field::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Field::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.name)
  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Field.name)
}
inline void Field::set_name(const char* value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name)
}
inline void Field::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name)
}

// optional string type_url = 6;
inline void Field::clear_type_url() {
  type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Field::type_url() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url)
  return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_type_url(const ::std::string& value) {
  
  type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url)
}
inline void Field::set_type_url(const char* value) {
  
  type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@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_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_type_url() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
  
  return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_allocated_type_url(::std::string* type_url) {
  if (type_url != NULL) {
    
  } else {
    
  }
  type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url)
}

// optional 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)
}

// optional 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_;
}

// optional string json_name = 10;
inline void Field::clear_json_name() {
  json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Field::json_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
  return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_json_name(const ::std::string& value) {
  
  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
}
inline void Field::set_json_name(const char* value) {
  
  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@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_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_json_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
  
  return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_allocated_json_name(::std::string* json_name) {
  if (json_name != NULL) {
    
  } else {
    
  }
  json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}

// optional string default_value = 11;
inline void Field::clear_default_value() {
  default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Field::default_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value)
  return default_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_default_value(const ::std::string& value) {
  
  default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
}
inline void Field::set_default_value(const char* value) {
  
  default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@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_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_default_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
  
  return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Field::set_allocated_default_value(::std::string* default_value) {
  if (default_value != NULL) {
    
  } else {
    
  }
  default_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value)
}

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

// Enum

// optional string name = 1;
inline void Enum::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Enum::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.name)
  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Enum::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Enum.name)
}
inline void Enum::set_name(const char* value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name)
}
inline void Enum::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Enum::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Enum::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_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_;
}

// optional .google.protobuf.SourceContext source_context = 4;
inline bool Enum::has_source_context() const {
  return !_is_default_instance_ && source_context_ != NULL;
}
inline void Enum::clear_source_context() {
  if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
  source_context_ = NULL;
}
inline const ::google::protobuf::SourceContext& Enum::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
  return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_;
}
inline ::google::protobuf::SourceContext* Enum::mutable_source_context() {
  
  if (source_context_ == NULL) {
    source_context_ = new ::google::protobuf::SourceContext;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context)
  return source_context_;
}
inline ::google::protobuf::SourceContext* Enum::release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context)
  
  ::google::protobuf::SourceContext* temp = source_context_;
  source_context_ = NULL;
  return temp;
}
inline void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
  delete source_context_;
  source_context_ = source_context;
  if (source_context) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
}

// optional .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

// optional string name = 1;
inline void EnumValue::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& EnumValue::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name)
  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void EnumValue::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name)
}
inline void EnumValue::set_name(const char* value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name)
}
inline void EnumValue::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* EnumValue::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void EnumValue::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name)
}

// optional 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

// optional string name = 1;
inline void Option::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Option::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Option.name)
  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Option::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.Option.name)
}
inline void Option::set_name(const char* value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name)
}
inline void Option::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@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_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Option::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Option::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name)
}

// optional .google.protobuf.Any value = 2;
inline bool Option::has_value() const {
  return !_is_default_instance_ && value_ != NULL;
}
inline void Option::clear_value() {
  if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_;
  value_ = NULL;
}
inline const ::google::protobuf::Any& Option::value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Option.value)
  return value_ != NULL ? *value_ : *default_instance_->value_;
}
inline ::google::protobuf::Any* Option::mutable_value() {
  
  if (value_ == NULL) {
    value_ = new ::google::protobuf::Any;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value)
  return value_;
}
inline ::google::protobuf::Any* Option::release_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.Option.value)
  
  ::google::protobuf::Any* temp = value_;
  value_ = NULL;
  return temp;
}
inline void Option::set_allocated_value(::google::protobuf::Any* value) {
  delete value_;
  value_ = value;
  if (value) {
    
  } else {
    
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value)
}

#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

#ifndef SWIG
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
#endif  // SWIG

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED
