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

#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED

#include <string>

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

#if GOOGLE_PROTOBUF_VERSION < 2006000
#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 2006001 < 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/generated_message_util.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>
// @@protoc_insertion_point(includes)

namespace google {
namespace protobuf {

// Internal implementation detail -- do not call these.
void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

class FileDescriptorSet;
class FileDescriptorProto;
class DescriptorProto;
class DescriptorProto_ExtensionRange;
class FieldDescriptorProto;
class OneofDescriptorProto;
class EnumDescriptorProto;
class EnumValueDescriptorProto;
class ServiceDescriptorProto;
class MethodDescriptorProto;
class FileOptions;
class MessageOptions;
class FieldOptions;
class EnumOptions;
class EnumValueOptions;
class ServiceOptions;
class MethodOptions;
class UninterpretedOption;
class UninterpretedOption_NamePart;
class SourceCodeInfo;
class SourceCodeInfo_Location;

enum FieldDescriptorProto_Type {
  FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
  FieldDescriptorProto_Type_TYPE_FLOAT = 2,
  FieldDescriptorProto_Type_TYPE_INT64 = 3,
  FieldDescriptorProto_Type_TYPE_UINT64 = 4,
  FieldDescriptorProto_Type_TYPE_INT32 = 5,
  FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
  FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
  FieldDescriptorProto_Type_TYPE_BOOL = 8,
  FieldDescriptorProto_Type_TYPE_STRING = 9,
  FieldDescriptorProto_Type_TYPE_GROUP = 10,
  FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
  FieldDescriptorProto_Type_TYPE_BYTES = 12,
  FieldDescriptorProto_Type_TYPE_UINT32 = 13,
  FieldDescriptorProto_Type_TYPE_ENUM = 14,
  FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
  FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
  FieldDescriptorProto_Type_TYPE_SINT32 = 17,
  FieldDescriptorProto_Type_TYPE_SINT64 = 18
};
LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value);
const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) {
  return ::google::protobuf::internal::NameOfEnum(
    FieldDescriptorProto_Type_descriptor(), value);
}
inline bool FieldDescriptorProto_Type_Parse(
    const ::std::string& name, FieldDescriptorProto_Type* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Type>(
    FieldDescriptorProto_Type_descriptor(), name, value);
}
enum FieldDescriptorProto_Label {
  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
  FieldDescriptorProto_Label_LABEL_REPEATED = 3
};
LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) {
  return ::google::protobuf::internal::NameOfEnum(
    FieldDescriptorProto_Label_descriptor(), value);
}
inline bool FieldDescriptorProto_Label_Parse(
    const ::std::string& name, FieldDescriptorProto_Label* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Label>(
    FieldDescriptorProto_Label_descriptor(), name, value);
}
enum FileOptions_OptimizeMode {
  FileOptions_OptimizeMode_SPEED = 1,
  FileOptions_OptimizeMode_CODE_SIZE = 2,
  FileOptions_OptimizeMode_LITE_RUNTIME = 3
};
LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value);
const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME;
const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) {
  return ::google::protobuf::internal::NameOfEnum(
    FileOptions_OptimizeMode_descriptor(), value);
}
inline bool FileOptions_OptimizeMode_Parse(
    const ::std::string& name, FileOptions_OptimizeMode* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FileOptions_OptimizeMode>(
    FileOptions_OptimizeMode_descriptor(), name, value);
}
enum FieldOptions_CType {
  FieldOptions_CType_STRING = 0,
  FieldOptions_CType_CORD = 1,
  FieldOptions_CType_STRING_PIECE = 2
};
LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor();
inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) {
  return ::google::protobuf::internal::NameOfEnum(
    FieldOptions_CType_descriptor(), value);
}
inline bool FieldOptions_CType_Parse(
    const ::std::string& name, FieldOptions_CType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FieldOptions_CType>(
    FieldOptions_CType_descriptor(), name, value);
}
// ===================================================================

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

  FileDescriptorSet(const FileDescriptorSet& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(FileDescriptorSet* other);

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

  FileDescriptorSet* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const FileDescriptorSet& from);
  void MergeFrom(const FileDescriptorSet& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // repeated .google.protobuf.FileDescriptorProto file = 1;
  inline int file_size() const;
  inline void clear_file();
  static const int kFileFieldNumber = 1;
  inline const ::google::protobuf::FileDescriptorProto& file(int index) const;
  inline ::google::protobuf::FileDescriptorProto* mutable_file(int index);
  inline ::google::protobuf::FileDescriptorProto* add_file();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
      file() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
      mutable_file();

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  FileDescriptorProto(const FileDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(FileDescriptorProto* other);

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

  FileDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const FileDescriptorProto& from);
  void MergeFrom(const FileDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // optional string package = 2;
  inline bool has_package() const;
  inline void clear_package();
  static const int kPackageFieldNumber = 2;
  inline const ::std::string& package() const;
  inline void set_package(const ::std::string& value);
  inline void set_package(const char* value);
  inline void set_package(const char* value, size_t size);
  inline ::std::string* mutable_package();
  inline ::std::string* release_package();
  inline void set_allocated_package(::std::string* package);

  // repeated string dependency = 3;
  inline int dependency_size() const;
  inline void clear_dependency();
  static const int kDependencyFieldNumber = 3;
  inline const ::std::string& dependency(int index) const;
  inline ::std::string* mutable_dependency(int index);
  inline void set_dependency(int index, const ::std::string& value);
  inline void set_dependency(int index, const char* value);
  inline void set_dependency(int index, const char* value, size_t size);
  inline ::std::string* add_dependency();
  inline void add_dependency(const ::std::string& value);
  inline void add_dependency(const char* value);
  inline void add_dependency(const char* value, size_t size);
  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();

  // repeated int32 public_dependency = 10;
  inline int public_dependency_size() const;
  inline void clear_public_dependency();
  static const int kPublicDependencyFieldNumber = 10;
  inline ::google::protobuf::int32 public_dependency(int index) const;
  inline void set_public_dependency(int index, ::google::protobuf::int32 value);
  inline void add_public_dependency(::google::protobuf::int32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
      public_dependency() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
      mutable_public_dependency();

  // repeated int32 weak_dependency = 11;
  inline int weak_dependency_size() const;
  inline void clear_weak_dependency();
  static const int kWeakDependencyFieldNumber = 11;
  inline ::google::protobuf::int32 weak_dependency(int index) const;
  inline void set_weak_dependency(int index, ::google::protobuf::int32 value);
  inline void add_weak_dependency(::google::protobuf::int32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
      weak_dependency() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
      mutable_weak_dependency();

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  inline int message_type_size() const;
  inline void clear_message_type();
  static const int kMessageTypeFieldNumber = 4;
  inline const ::google::protobuf::DescriptorProto& message_type(int index) const;
  inline ::google::protobuf::DescriptorProto* mutable_message_type(int index);
  inline ::google::protobuf::DescriptorProto* add_message_type();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
      message_type() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
      mutable_message_type();

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  inline int enum_type_size() const;
  inline void clear_enum_type();
  static const int kEnumTypeFieldNumber = 5;
  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
      enum_type() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
      mutable_enum_type();

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  inline int service_size() const;
  inline void clear_service();
  static const int kServiceFieldNumber = 6;
  inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
  inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
  inline ::google::protobuf::ServiceDescriptorProto* add_service();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
      service() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
      mutable_service();

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  inline int extension_size() const;
  inline void clear_extension();
  static const int kExtensionFieldNumber = 7;
  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
  inline ::google::protobuf::FieldDescriptorProto* add_extension();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
      extension() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
      mutable_extension();

  // optional .google.protobuf.FileOptions options = 8;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 8;
  inline const ::google::protobuf::FileOptions& options() const;
  inline ::google::protobuf::FileOptions* mutable_options();
  inline ::google::protobuf::FileOptions* release_options();
  inline void set_allocated_options(::google::protobuf::FileOptions* options);

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  inline bool has_source_code_info() const;
  inline void clear_source_code_info();
  static const int kSourceCodeInfoFieldNumber = 9;
  inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
  inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
  inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
  inline void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info);

  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_package();
  inline void clear_has_package();
  inline void set_has_options();
  inline void clear_has_options();
  inline void set_has_source_code_info();
  inline void clear_has_source_code_info();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::std::string* package_;
  ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
  ::google::protobuf::FileOptions* options_;
  ::google::protobuf::SourceCodeInfo* source_code_info_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(DescriptorProto_ExtensionRange* other);

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

  DescriptorProto_ExtensionRange* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const DescriptorProto_ExtensionRange& from);
  void MergeFrom(const DescriptorProto_ExtensionRange& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional int32 start = 1;
  inline bool has_start() const;
  inline void clear_start();
  static const int kStartFieldNumber = 1;
  inline ::google::protobuf::int32 start() const;
  inline void set_start(::google::protobuf::int32 value);

  // optional int32 end = 2;
  inline bool has_end() const;
  inline void clear_end();
  static const int kEndFieldNumber = 2;
  inline ::google::protobuf::int32 end() const;
  inline void set_end(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
 private:
  inline void set_has_start();
  inline void clear_has_start();
  inline void set_has_end();
  inline void clear_has_end();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::int32 start_;
  ::google::protobuf::int32 end_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  DescriptorProto(const DescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(DescriptorProto* other);

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

  DescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const DescriptorProto& from);
  void MergeFrom(const DescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

  typedef DescriptorProto_ExtensionRange ExtensionRange;

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

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

  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  inline int field_size() const;
  inline void clear_field();
  static const int kFieldFieldNumber = 2;
  inline const ::google::protobuf::FieldDescriptorProto& field(int index) const;
  inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
  inline ::google::protobuf::FieldDescriptorProto* add_field();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
      field() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
      mutable_field();

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  inline int extension_size() const;
  inline void clear_extension();
  static const int kExtensionFieldNumber = 6;
  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
  inline ::google::protobuf::FieldDescriptorProto* add_extension();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
      extension() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
      mutable_extension();

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  inline int nested_type_size() const;
  inline void clear_nested_type();
  static const int kNestedTypeFieldNumber = 3;
  inline const ::google::protobuf::DescriptorProto& nested_type(int index) const;
  inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
  inline ::google::protobuf::DescriptorProto* add_nested_type();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
      nested_type() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
      mutable_nested_type();

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  inline int enum_type_size() const;
  inline void clear_enum_type();
  static const int kEnumTypeFieldNumber = 4;
  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
      enum_type() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
      mutable_enum_type();

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  inline int extension_range_size() const;
  inline void clear_extension_range();
  static const int kExtensionRangeFieldNumber = 5;
  inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
  inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
  inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
      extension_range() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
      mutable_extension_range();

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  inline int oneof_decl_size() const;
  inline void clear_oneof_decl();
  static const int kOneofDeclFieldNumber = 8;
  inline const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
  inline ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
  inline ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
      oneof_decl() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
      mutable_oneof_decl();

  // optional .google.protobuf.MessageOptions options = 7;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 7;
  inline const ::google::protobuf::MessageOptions& options() const;
  inline ::google::protobuf::MessageOptions* mutable_options();
  inline ::google::protobuf::MessageOptions* release_options();
  inline void set_allocated_options(::google::protobuf::MessageOptions* options);

  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_options();
  inline void clear_has_options();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
  ::google::protobuf::MessageOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  FieldDescriptorProto(const FieldDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(FieldDescriptorProto* other);

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

  FieldDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const FieldDescriptorProto& from);
  void MergeFrom(const FieldDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

  typedef FieldDescriptorProto_Type Type;
  static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
  static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
  static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
  static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
  static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
  static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
  static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
  static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
  static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
  static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
  static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
  static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
  static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
  static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
  static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
  static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
  static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
  static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
  static inline bool Type_IsValid(int value) {
    return FieldDescriptorProto_Type_IsValid(value);
  }
  static const Type Type_MIN =
    FieldDescriptorProto_Type_Type_MIN;
  static const Type Type_MAX =
    FieldDescriptorProto_Type_Type_MAX;
  static const int Type_ARRAYSIZE =
    FieldDescriptorProto_Type_Type_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Type_descriptor() {
    return FieldDescriptorProto_Type_descriptor();
  }
  static inline const ::std::string& Type_Name(Type value) {
    return FieldDescriptorProto_Type_Name(value);
  }
  static inline bool Type_Parse(const ::std::string& name,
      Type* value) {
    return FieldDescriptorProto_Type_Parse(name, value);
  }

  typedef FieldDescriptorProto_Label Label;
  static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
  static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
  static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
  static inline bool Label_IsValid(int value) {
    return FieldDescriptorProto_Label_IsValid(value);
  }
  static const Label Label_MIN =
    FieldDescriptorProto_Label_Label_MIN;
  static const Label Label_MAX =
    FieldDescriptorProto_Label_Label_MAX;
  static const int Label_ARRAYSIZE =
    FieldDescriptorProto_Label_Label_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Label_descriptor() {
    return FieldDescriptorProto_Label_descriptor();
  }
  static inline const ::std::string& Label_Name(Label value) {
    return FieldDescriptorProto_Label_Name(value);
  }
  static inline bool Label_Parse(const ::std::string& name,
      Label* value) {
    return FieldDescriptorProto_Label_Parse(name, value);
  }

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

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

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

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  inline bool has_label() const;
  inline void clear_label();
  static const int kLabelFieldNumber = 4;
  inline ::google::protobuf::FieldDescriptorProto_Label label() const;
  inline void set_label(::google::protobuf::FieldDescriptorProto_Label value);

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 5;
  inline ::google::protobuf::FieldDescriptorProto_Type type() const;
  inline void set_type(::google::protobuf::FieldDescriptorProto_Type value);

  // optional string type_name = 6;
  inline bool has_type_name() const;
  inline void clear_type_name();
  static const int kTypeNameFieldNumber = 6;
  inline const ::std::string& type_name() const;
  inline void set_type_name(const ::std::string& value);
  inline void set_type_name(const char* value);
  inline void set_type_name(const char* value, size_t size);
  inline ::std::string* mutable_type_name();
  inline ::std::string* release_type_name();
  inline void set_allocated_type_name(::std::string* type_name);

  // optional string extendee = 2;
  inline bool has_extendee() const;
  inline void clear_extendee();
  static const int kExtendeeFieldNumber = 2;
  inline const ::std::string& extendee() const;
  inline void set_extendee(const ::std::string& value);
  inline void set_extendee(const char* value);
  inline void set_extendee(const char* value, size_t size);
  inline ::std::string* mutable_extendee();
  inline ::std::string* release_extendee();
  inline void set_allocated_extendee(::std::string* extendee);

  // optional string default_value = 7;
  inline bool has_default_value() const;
  inline void clear_default_value();
  static const int kDefaultValueFieldNumber = 7;
  inline const ::std::string& default_value() const;
  inline void set_default_value(const ::std::string& value);
  inline void set_default_value(const char* value);
  inline void set_default_value(const char* value, size_t size);
  inline ::std::string* mutable_default_value();
  inline ::std::string* release_default_value();
  inline void set_allocated_default_value(::std::string* default_value);

  // optional int32 oneof_index = 9;
  inline bool has_oneof_index() const;
  inline void clear_oneof_index();
  static const int kOneofIndexFieldNumber = 9;
  inline ::google::protobuf::int32 oneof_index() const;
  inline void set_oneof_index(::google::protobuf::int32 value);

  // optional .google.protobuf.FieldOptions options = 8;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 8;
  inline const ::google::protobuf::FieldOptions& options() const;
  inline ::google::protobuf::FieldOptions* mutable_options();
  inline ::google::protobuf::FieldOptions* release_options();
  inline void set_allocated_options(::google::protobuf::FieldOptions* options);

  // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_number();
  inline void clear_has_number();
  inline void set_has_label();
  inline void clear_has_label();
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_type_name();
  inline void clear_has_type_name();
  inline void set_has_extendee();
  inline void clear_has_extendee();
  inline void set_has_default_value();
  inline void clear_has_default_value();
  inline void set_has_oneof_index();
  inline void clear_has_oneof_index();
  inline void set_has_options();
  inline void clear_has_options();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::google::protobuf::int32 number_;
  int label_;
  ::std::string* type_name_;
  ::std::string* extendee_;
  int type_;
  ::google::protobuf::int32 oneof_index_;
  ::std::string* default_value_;
  ::google::protobuf::FieldOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  OneofDescriptorProto(const OneofDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(OneofDescriptorProto* other);

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

  OneofDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const OneofDescriptorProto& from);
  void MergeFrom(const OneofDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  EnumDescriptorProto(const EnumDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(EnumDescriptorProto* other);

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

  EnumDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const EnumDescriptorProto& from);
  void MergeFrom(const EnumDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  inline int value_size() const;
  inline void clear_value();
  static const int kValueFieldNumber = 2;
  inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
  inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
  inline ::google::protobuf::EnumValueDescriptorProto* add_value();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
      value() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
      mutable_value();

  // optional .google.protobuf.EnumOptions options = 3;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 3;
  inline const ::google::protobuf::EnumOptions& options() const;
  inline ::google::protobuf::EnumOptions* mutable_options();
  inline ::google::protobuf::EnumOptions* release_options();
  inline void set_allocated_options(::google::protobuf::EnumOptions* options);

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_options();
  inline void clear_has_options();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
  ::google::protobuf::EnumOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  EnumValueDescriptorProto(const EnumValueDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(EnumValueDescriptorProto* other);

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

  EnumValueDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const EnumValueDescriptorProto& from);
  void MergeFrom(const EnumValueDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

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

  // optional .google.protobuf.EnumValueOptions options = 3;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 3;
  inline const ::google::protobuf::EnumValueOptions& options() const;
  inline ::google::protobuf::EnumValueOptions* mutable_options();
  inline ::google::protobuf::EnumValueOptions* release_options();
  inline void set_allocated_options(::google::protobuf::EnumValueOptions* options);

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_number();
  inline void clear_has_number();
  inline void set_has_options();
  inline void clear_has_options();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::google::protobuf::EnumValueOptions* options_;
  ::google::protobuf::int32 number_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  ServiceDescriptorProto(const ServiceDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(ServiceDescriptorProto* other);

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

  ServiceDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const ServiceDescriptorProto& from);
  void MergeFrom(const ServiceDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  inline int method_size() const;
  inline void clear_method();
  static const int kMethodFieldNumber = 2;
  inline const ::google::protobuf::MethodDescriptorProto& method(int index) const;
  inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
  inline ::google::protobuf::MethodDescriptorProto* add_method();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
      method() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
      mutable_method();

  // optional .google.protobuf.ServiceOptions options = 3;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 3;
  inline const ::google::protobuf::ServiceOptions& options() const;
  inline ::google::protobuf::ServiceOptions* mutable_options();
  inline ::google::protobuf::ServiceOptions* release_options();
  inline void set_allocated_options(::google::protobuf::ServiceOptions* options);

  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_options();
  inline void clear_has_options();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
  ::google::protobuf::ServiceOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  MethodDescriptorProto(const MethodDescriptorProto& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(MethodDescriptorProto* other);

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

  MethodDescriptorProto* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MethodDescriptorProto& from);
  void MergeFrom(const MethodDescriptorProto& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // optional string input_type = 2;
  inline bool has_input_type() const;
  inline void clear_input_type();
  static const int kInputTypeFieldNumber = 2;
  inline const ::std::string& input_type() const;
  inline void set_input_type(const ::std::string& value);
  inline void set_input_type(const char* value);
  inline void set_input_type(const char* value, size_t size);
  inline ::std::string* mutable_input_type();
  inline ::std::string* release_input_type();
  inline void set_allocated_input_type(::std::string* input_type);

  // optional string output_type = 3;
  inline bool has_output_type() const;
  inline void clear_output_type();
  static const int kOutputTypeFieldNumber = 3;
  inline const ::std::string& output_type() const;
  inline void set_output_type(const ::std::string& value);
  inline void set_output_type(const char* value);
  inline void set_output_type(const char* value, size_t size);
  inline ::std::string* mutable_output_type();
  inline ::std::string* release_output_type();
  inline void set_allocated_output_type(::std::string* output_type);

  // optional .google.protobuf.MethodOptions options = 4;
  inline bool has_options() const;
  inline void clear_options();
  static const int kOptionsFieldNumber = 4;
  inline const ::google::protobuf::MethodOptions& options() const;
  inline ::google::protobuf::MethodOptions* mutable_options();
  inline ::google::protobuf::MethodOptions* release_options();
  inline void set_allocated_options(::google::protobuf::MethodOptions* options);

  // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_input_type();
  inline void clear_has_input_type();
  inline void set_has_output_type();
  inline void clear_has_output_type();
  inline void set_has_options();
  inline void clear_has_options();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::std::string* input_type_;
  ::std::string* output_type_;
  ::google::protobuf::MethodOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  FileOptions(const FileOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(FileOptions* other);

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

  FileOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const FileOptions& from);
  void MergeFrom(const FileOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

  typedef FileOptions_OptimizeMode OptimizeMode;
  static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
  static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
  static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME;
  static inline bool OptimizeMode_IsValid(int value) {
    return FileOptions_OptimizeMode_IsValid(value);
  }
  static const OptimizeMode OptimizeMode_MIN =
    FileOptions_OptimizeMode_OptimizeMode_MIN;
  static const OptimizeMode OptimizeMode_MAX =
    FileOptions_OptimizeMode_OptimizeMode_MAX;
  static const int OptimizeMode_ARRAYSIZE =
    FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  OptimizeMode_descriptor() {
    return FileOptions_OptimizeMode_descriptor();
  }
  static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) {
    return FileOptions_OptimizeMode_Name(value);
  }
  static inline bool OptimizeMode_Parse(const ::std::string& name,
      OptimizeMode* value) {
    return FileOptions_OptimizeMode_Parse(name, value);
  }

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

  // optional string java_package = 1;
  inline bool has_java_package() const;
  inline void clear_java_package();
  static const int kJavaPackageFieldNumber = 1;
  inline const ::std::string& java_package() const;
  inline void set_java_package(const ::std::string& value);
  inline void set_java_package(const char* value);
  inline void set_java_package(const char* value, size_t size);
  inline ::std::string* mutable_java_package();
  inline ::std::string* release_java_package();
  inline void set_allocated_java_package(::std::string* java_package);

  // optional string java_outer_classname = 8;
  inline bool has_java_outer_classname() const;
  inline void clear_java_outer_classname();
  static const int kJavaOuterClassnameFieldNumber = 8;
  inline const ::std::string& java_outer_classname() const;
  inline void set_java_outer_classname(const ::std::string& value);
  inline void set_java_outer_classname(const char* value);
  inline void set_java_outer_classname(const char* value, size_t size);
  inline ::std::string* mutable_java_outer_classname();
  inline ::std::string* release_java_outer_classname();
  inline void set_allocated_java_outer_classname(::std::string* java_outer_classname);

  // optional bool java_multiple_files = 10 [default = false];
  inline bool has_java_multiple_files() const;
  inline void clear_java_multiple_files();
  static const int kJavaMultipleFilesFieldNumber = 10;
  inline bool java_multiple_files() const;
  inline void set_java_multiple_files(bool value);

  // optional bool java_generate_equals_and_hash = 20 [default = false];
  inline bool has_java_generate_equals_and_hash() const;
  inline void clear_java_generate_equals_and_hash();
  static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
  inline bool java_generate_equals_and_hash() const;
  inline void set_java_generate_equals_and_hash(bool value);

  // optional bool java_string_check_utf8 = 27 [default = false];
  inline bool has_java_string_check_utf8() const;
  inline void clear_java_string_check_utf8();
  static const int kJavaStringCheckUtf8FieldNumber = 27;
  inline bool java_string_check_utf8() const;
  inline void set_java_string_check_utf8(bool value);

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  inline bool has_optimize_for() const;
  inline void clear_optimize_for();
  static const int kOptimizeForFieldNumber = 9;
  inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
  inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);

  // optional string go_package = 11;
  inline bool has_go_package() const;
  inline void clear_go_package();
  static const int kGoPackageFieldNumber = 11;
  inline const ::std::string& go_package() const;
  inline void set_go_package(const ::std::string& value);
  inline void set_go_package(const char* value);
  inline void set_go_package(const char* value, size_t size);
  inline ::std::string* mutable_go_package();
  inline ::std::string* release_go_package();
  inline void set_allocated_go_package(::std::string* go_package);

  // optional bool cc_generic_services = 16 [default = false];
  inline bool has_cc_generic_services() const;
  inline void clear_cc_generic_services();
  static const int kCcGenericServicesFieldNumber = 16;
  inline bool cc_generic_services() const;
  inline void set_cc_generic_services(bool value);

  // optional bool java_generic_services = 17 [default = false];
  inline bool has_java_generic_services() const;
  inline void clear_java_generic_services();
  static const int kJavaGenericServicesFieldNumber = 17;
  inline bool java_generic_services() const;
  inline void set_java_generic_services(bool value);

  // optional bool py_generic_services = 18 [default = false];
  inline bool has_py_generic_services() const;
  inline void clear_py_generic_services();
  static const int kPyGenericServicesFieldNumber = 18;
  inline bool py_generic_services() const;
  inline void set_py_generic_services(bool value);

  // optional bool deprecated = 23 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 23;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // optional bool javanano_use_deprecated_package = 38;
  inline bool has_javanano_use_deprecated_package() const;
  inline void clear_javanano_use_deprecated_package();
  static const int kJavananoUseDeprecatedPackageFieldNumber = 38;
  inline bool javanano_use_deprecated_package() const;
  inline void set_javanano_use_deprecated_package(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
 private:
  inline void set_has_java_package();
  inline void clear_has_java_package();
  inline void set_has_java_outer_classname();
  inline void clear_has_java_outer_classname();
  inline void set_has_java_multiple_files();
  inline void clear_has_java_multiple_files();
  inline void set_has_java_generate_equals_and_hash();
  inline void clear_has_java_generate_equals_and_hash();
  inline void set_has_java_string_check_utf8();
  inline void clear_has_java_string_check_utf8();
  inline void set_has_optimize_for();
  inline void clear_has_optimize_for();
  inline void set_has_go_package();
  inline void clear_has_go_package();
  inline void set_has_cc_generic_services();
  inline void clear_has_cc_generic_services();
  inline void set_has_java_generic_services();
  inline void clear_has_java_generic_services();
  inline void set_has_py_generic_services();
  inline void clear_has_py_generic_services();
  inline void set_has_deprecated();
  inline void clear_has_deprecated();
  inline void set_has_javanano_use_deprecated_package();
  inline void clear_has_javanano_use_deprecated_package();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* java_package_;
  ::std::string* java_outer_classname_;
  bool java_multiple_files_;
  bool java_generate_equals_and_hash_;
  bool java_string_check_utf8_;
  bool cc_generic_services_;
  int optimize_for_;
  ::std::string* go_package_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool java_generic_services_;
  bool py_generic_services_;
  bool deprecated_;
  bool javanano_use_deprecated_package_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  MessageOptions(const MessageOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(MessageOptions* other);

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

  MessageOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MessageOptions& from);
  void MergeFrom(const MessageOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional bool message_set_wire_format = 1 [default = false];
  inline bool has_message_set_wire_format() const;
  inline void clear_message_set_wire_format();
  static const int kMessageSetWireFormatFieldNumber = 1;
  inline bool message_set_wire_format() const;
  inline void set_message_set_wire_format(bool value);

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  inline bool has_no_standard_descriptor_accessor() const;
  inline void clear_no_standard_descriptor_accessor();
  static const int kNoStandardDescriptorAccessorFieldNumber = 2;
  inline bool no_standard_descriptor_accessor() const;
  inline void set_no_standard_descriptor_accessor(bool value);

  // optional bool deprecated = 3 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 3;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
 private:
  inline void set_has_message_set_wire_format();
  inline void clear_has_message_set_wire_format();
  inline void set_has_no_standard_descriptor_accessor();
  inline void clear_has_no_standard_descriptor_accessor();
  inline void set_has_deprecated();
  inline void clear_has_deprecated();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool message_set_wire_format_;
  bool no_standard_descriptor_accessor_;
  bool deprecated_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  FieldOptions(const FieldOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(FieldOptions* other);

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

  FieldOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const FieldOptions& from);
  void MergeFrom(const FieldOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

  typedef FieldOptions_CType CType;
  static const CType STRING = FieldOptions_CType_STRING;
  static const CType CORD = FieldOptions_CType_CORD;
  static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE;
  static inline bool CType_IsValid(int value) {
    return FieldOptions_CType_IsValid(value);
  }
  static const CType CType_MIN =
    FieldOptions_CType_CType_MIN;
  static const CType CType_MAX =
    FieldOptions_CType_CType_MAX;
  static const int CType_ARRAYSIZE =
    FieldOptions_CType_CType_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  CType_descriptor() {
    return FieldOptions_CType_descriptor();
  }
  static inline const ::std::string& CType_Name(CType value) {
    return FieldOptions_CType_Name(value);
  }
  static inline bool CType_Parse(const ::std::string& name,
      CType* value) {
    return FieldOptions_CType_Parse(name, value);
  }

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

  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  inline bool has_ctype() const;
  inline void clear_ctype();
  static const int kCtypeFieldNumber = 1;
  inline ::google::protobuf::FieldOptions_CType ctype() const;
  inline void set_ctype(::google::protobuf::FieldOptions_CType value);

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

  // optional bool lazy = 5 [default = false];
  inline bool has_lazy() const;
  inline void clear_lazy();
  static const int kLazyFieldNumber = 5;
  inline bool lazy() const;
  inline void set_lazy(bool value);

  // optional bool deprecated = 3 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 3;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // optional string experimental_map_key = 9;
  inline bool has_experimental_map_key() const;
  inline void clear_experimental_map_key();
  static const int kExperimentalMapKeyFieldNumber = 9;
  inline const ::std::string& experimental_map_key() const;
  inline void set_experimental_map_key(const ::std::string& value);
  inline void set_experimental_map_key(const char* value);
  inline void set_experimental_map_key(const char* value, size_t size);
  inline ::std::string* mutable_experimental_map_key();
  inline ::std::string* release_experimental_map_key();
  inline void set_allocated_experimental_map_key(::std::string* experimental_map_key);

  // optional bool weak = 10 [default = false];
  inline bool has_weak() const;
  inline void clear_weak();
  static const int kWeakFieldNumber = 10;
  inline bool weak() const;
  inline void set_weak(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
 private:
  inline void set_has_ctype();
  inline void clear_has_ctype();
  inline void set_has_packed();
  inline void clear_has_packed();
  inline void set_has_lazy();
  inline void clear_has_lazy();
  inline void set_has_deprecated();
  inline void clear_has_deprecated();
  inline void set_has_experimental_map_key();
  inline void clear_has_experimental_map_key();
  inline void set_has_weak();
  inline void clear_has_weak();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  int ctype_;
  bool packed_;
  bool lazy_;
  bool deprecated_;
  bool weak_;
  ::std::string* experimental_map_key_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  EnumOptions(const EnumOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(EnumOptions* other);

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

  EnumOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const EnumOptions& from);
  void MergeFrom(const EnumOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional bool allow_alias = 2;
  inline bool has_allow_alias() const;
  inline void clear_allow_alias();
  static const int kAllowAliasFieldNumber = 2;
  inline bool allow_alias() const;
  inline void set_allow_alias(bool value);

  // optional bool deprecated = 3 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 3;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
 private:
  inline void set_has_allow_alias();
  inline void clear_has_allow_alias();
  inline void set_has_deprecated();
  inline void clear_has_deprecated();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool allow_alias_;
  bool deprecated_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  EnumValueOptions(const EnumValueOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(EnumValueOptions* other);

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

  EnumValueOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const EnumValueOptions& from);
  void MergeFrom(const EnumValueOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional bool deprecated = 1 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 1;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
 private:
  inline void set_has_deprecated();
  inline void clear_has_deprecated();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool deprecated_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  ServiceOptions(const ServiceOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(ServiceOptions* other);

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

  ServiceOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const ServiceOptions& from);
  void MergeFrom(const ServiceOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional bool deprecated = 33 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 33;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
 private:
  inline void set_has_deprecated();
  inline void clear_has_deprecated();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool deprecated_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  MethodOptions(const MethodOptions& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(MethodOptions* other);

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

  MethodOptions* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MethodOptions& from);
  void MergeFrom(const MethodOptions& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional bool deprecated = 33 [default = false];
  inline bool has_deprecated() const;
  inline void clear_deprecated();
  static const int kDeprecatedFieldNumber = 33;
  inline bool deprecated() const;
  inline void set_deprecated(bool value);

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  inline int uninterpreted_option_size() const;
  inline void clear_uninterpreted_option();
  static const int kUninterpretedOptionFieldNumber = 999;
  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
      uninterpreted_option() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
      mutable_uninterpreted_option();

  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
  // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
 private:
  inline void set_has_deprecated();
  inline void clear_has_deprecated();

  ::google::protobuf::internal::ExtensionSet _extensions_;

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool deprecated_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(UninterpretedOption_NamePart* other);

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

  UninterpretedOption_NamePart* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const UninterpretedOption_NamePart& from);
  void MergeFrom(const UninterpretedOption_NamePart& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // required string name_part = 1;
  inline bool has_name_part() const;
  inline void clear_name_part();
  static const int kNamePartFieldNumber = 1;
  inline const ::std::string& name_part() const;
  inline void set_name_part(const ::std::string& value);
  inline void set_name_part(const char* value);
  inline void set_name_part(const char* value, size_t size);
  inline ::std::string* mutable_name_part();
  inline ::std::string* release_name_part();
  inline void set_allocated_name_part(::std::string* name_part);

  // required bool is_extension = 2;
  inline bool has_is_extension() const;
  inline void clear_is_extension();
  static const int kIsExtensionFieldNumber = 2;
  inline bool is_extension() const;
  inline void set_is_extension(bool value);

  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
 private:
  inline void set_has_name_part();
  inline void clear_has_name_part();
  inline void set_has_is_extension();
  inline void clear_has_is_extension();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_part_;
  bool is_extension_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  UninterpretedOption(const UninterpretedOption& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(UninterpretedOption* other);

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

  UninterpretedOption* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const UninterpretedOption& from);
  void MergeFrom(const UninterpretedOption& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

  typedef UninterpretedOption_NamePart NamePart;

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

  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  inline int name_size() const;
  inline void clear_name();
  static const int kNameFieldNumber = 2;
  inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
  inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
  inline ::google::protobuf::UninterpretedOption_NamePart* add_name();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
      name() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
      mutable_name();

  // optional string identifier_value = 3;
  inline bool has_identifier_value() const;
  inline void clear_identifier_value();
  static const int kIdentifierValueFieldNumber = 3;
  inline const ::std::string& identifier_value() const;
  inline void set_identifier_value(const ::std::string& value);
  inline void set_identifier_value(const char* value);
  inline void set_identifier_value(const char* value, size_t size);
  inline ::std::string* mutable_identifier_value();
  inline ::std::string* release_identifier_value();
  inline void set_allocated_identifier_value(::std::string* identifier_value);

  // optional uint64 positive_int_value = 4;
  inline bool has_positive_int_value() const;
  inline void clear_positive_int_value();
  static const int kPositiveIntValueFieldNumber = 4;
  inline ::google::protobuf::uint64 positive_int_value() const;
  inline void set_positive_int_value(::google::protobuf::uint64 value);

  // optional int64 negative_int_value = 5;
  inline bool has_negative_int_value() const;
  inline void clear_negative_int_value();
  static const int kNegativeIntValueFieldNumber = 5;
  inline ::google::protobuf::int64 negative_int_value() const;
  inline void set_negative_int_value(::google::protobuf::int64 value);

  // optional double double_value = 6;
  inline bool has_double_value() const;
  inline void clear_double_value();
  static const int kDoubleValueFieldNumber = 6;
  inline double double_value() const;
  inline void set_double_value(double value);

  // optional bytes string_value = 7;
  inline bool has_string_value() const;
  inline void clear_string_value();
  static const int kStringValueFieldNumber = 7;
  inline const ::std::string& string_value() const;
  inline void set_string_value(const ::std::string& value);
  inline void set_string_value(const char* value);
  inline void set_string_value(const void* value, size_t size);
  inline ::std::string* mutable_string_value();
  inline ::std::string* release_string_value();
  inline void set_allocated_string_value(::std::string* string_value);

  // optional string aggregate_value = 8;
  inline bool has_aggregate_value() const;
  inline void clear_aggregate_value();
  static const int kAggregateValueFieldNumber = 8;
  inline const ::std::string& aggregate_value() const;
  inline void set_aggregate_value(const ::std::string& value);
  inline void set_aggregate_value(const char* value);
  inline void set_aggregate_value(const char* value, size_t size);
  inline ::std::string* mutable_aggregate_value();
  inline ::std::string* release_aggregate_value();
  inline void set_allocated_aggregate_value(::std::string* aggregate_value);

  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
 private:
  inline void set_has_identifier_value();
  inline void clear_has_identifier_value();
  inline void set_has_positive_int_value();
  inline void clear_has_positive_int_value();
  inline void set_has_negative_int_value();
  inline void clear_has_negative_int_value();
  inline void set_has_double_value();
  inline void clear_has_double_value();
  inline void set_has_string_value();
  inline void clear_has_string_value();
  inline void set_has_aggregate_value();
  inline void clear_has_aggregate_value();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
  ::std::string* identifier_value_;
  ::google::protobuf::uint64 positive_int_value_;
  ::google::protobuf::int64 negative_int_value_;
  double double_value_;
  ::std::string* string_value_;
  ::std::string* aggregate_value_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  SourceCodeInfo_Location(const SourceCodeInfo_Location& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(SourceCodeInfo_Location* other);

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

  SourceCodeInfo_Location* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const SourceCodeInfo_Location& from);
  void MergeFrom(const SourceCodeInfo_Location& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // repeated int32 path = 1 [packed = true];
  inline int path_size() const;
  inline void clear_path();
  static const int kPathFieldNumber = 1;
  inline ::google::protobuf::int32 path(int index) const;
  inline void set_path(int index, ::google::protobuf::int32 value);
  inline void add_path(::google::protobuf::int32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
      path() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
      mutable_path();

  // repeated int32 span = 2 [packed = true];
  inline int span_size() const;
  inline void clear_span();
  static const int kSpanFieldNumber = 2;
  inline ::google::protobuf::int32 span(int index) const;
  inline void set_span(int index, ::google::protobuf::int32 value);
  inline void add_span(::google::protobuf::int32 value);
  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
      span() const;
  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
      mutable_span();

  // optional string leading_comments = 3;
  inline bool has_leading_comments() const;
  inline void clear_leading_comments();
  static const int kLeadingCommentsFieldNumber = 3;
  inline const ::std::string& leading_comments() const;
  inline void set_leading_comments(const ::std::string& value);
  inline void set_leading_comments(const char* value);
  inline void set_leading_comments(const char* value, size_t size);
  inline ::std::string* mutable_leading_comments();
  inline ::std::string* release_leading_comments();
  inline void set_allocated_leading_comments(::std::string* leading_comments);

  // optional string trailing_comments = 4;
  inline bool has_trailing_comments() const;
  inline void clear_trailing_comments();
  static const int kTrailingCommentsFieldNumber = 4;
  inline const ::std::string& trailing_comments() const;
  inline void set_trailing_comments(const ::std::string& value);
  inline void set_trailing_comments(const char* value);
  inline void set_trailing_comments(const char* value, size_t size);
  inline ::std::string* mutable_trailing_comments();
  inline ::std::string* release_trailing_comments();
  inline void set_allocated_trailing_comments(::std::string* trailing_comments);

  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
 private:
  inline void set_has_leading_comments();
  inline void clear_has_leading_comments();
  inline void set_has_trailing_comments();
  inline void clear_has_trailing_comments();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
  mutable int _path_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
  mutable int _span_cached_byte_size_;
  ::std::string* leading_comments_;
  ::std::string* trailing_comments_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  SourceCodeInfo(const SourceCodeInfo& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _unknown_fields_;
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(SourceCodeInfo* other);

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

  SourceCodeInfo* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const SourceCodeInfo& from);
  void MergeFrom(const SourceCodeInfo& 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;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

  typedef SourceCodeInfo_Location Location;

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

  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  inline int location_size() const;
  inline void clear_location();
  static const int kLocationFieldNumber = 1;
  inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
  inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
  inline ::google::protobuf::SourceCodeInfo_Location* add_location();
  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
      location() const;
  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
      mutable_location();

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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


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

// FileDescriptorSet

// repeated .google.protobuf.FileDescriptorProto file = 1;
inline int FileDescriptorSet::file_size() const {
  return file_.size();
}
inline void FileDescriptorSet::clear_file() {
  file_.Clear();
}
inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
  return file_.Get(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
  return file_.Mutable(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
  return file_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
FileDescriptorSet::file() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
  return file_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
FileDescriptorSet::mutable_file() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
  return &file_;
}

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

// FileDescriptorProto

// optional string name = 1;
inline bool FileDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FileDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FileDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FileDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& FileDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
  return *name_;
}
inline void FileDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
}
inline void FileDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
}
inline void FileDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name)
}
inline ::std::string* FileDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
  return name_;
}
inline ::std::string* FileDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FileDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
}

// optional string package = 2;
inline bool FileDescriptorProto::has_package() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FileDescriptorProto::set_has_package() {
  _has_bits_[0] |= 0x00000002u;
}
inline void FileDescriptorProto::clear_has_package() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void FileDescriptorProto::clear_package() {
  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    package_->clear();
  }
  clear_has_package();
}
inline const ::std::string& FileDescriptorProto::package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
  return *package_;
}
inline void FileDescriptorProto::set_package(const ::std::string& value) {
  set_has_package();
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    package_ = new ::std::string;
  }
  package_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
}
inline void FileDescriptorProto::set_package(const char* value) {
  set_has_package();
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    package_ = new ::std::string;
  }
  package_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
}
inline void FileDescriptorProto::set_package(const char* value, size_t size) {
  set_has_package();
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    package_ = new ::std::string;
  }
  package_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package)
}
inline ::std::string* FileDescriptorProto::mutable_package() {
  set_has_package();
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    package_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
  return package_;
}
inline ::std::string* FileDescriptorProto::release_package() {
  clear_has_package();
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = package_;
    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FileDescriptorProto::set_allocated_package(::std::string* package) {
  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete package_;
  }
  if (package) {
    set_has_package();
    package_ = package;
  } else {
    clear_has_package();
    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
}

// repeated string dependency = 3;
inline int FileDescriptorProto::dependency_size() const {
  return dependency_.size();
}
inline void FileDescriptorProto::clear_dependency() {
  dependency_.Clear();
}
inline const ::std::string& FileDescriptorProto::dependency(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
  return dependency_.Get(index);
}
inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
  return dependency_.Mutable(index);
}
inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
  dependency_.Mutable(index)->assign(value);
}
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
  dependency_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
  dependency_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline ::std::string* FileDescriptorProto::add_dependency() {
  return dependency_.Add();
}
inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
  dependency_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(const char* value) {
  dependency_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
  dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
FileDescriptorProto::dependency() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
  return dependency_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
FileDescriptorProto::mutable_dependency() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
  return &dependency_;
}

// repeated int32 public_dependency = 10;
inline int FileDescriptorProto::public_dependency_size() const {
  return public_dependency_.size();
}
inline void FileDescriptorProto::clear_public_dependency() {
  public_dependency_.Clear();
}
inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency)
  return public_dependency_.Get(index);
}
inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) {
  public_dependency_.Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
}
inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) {
  public_dependency_.Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
FileDescriptorProto::public_dependency() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
  return public_dependency_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
FileDescriptorProto::mutable_public_dependency() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
  return &public_dependency_;
}

// repeated int32 weak_dependency = 11;
inline int FileDescriptorProto::weak_dependency_size() const {
  return weak_dependency_.size();
}
inline void FileDescriptorProto::clear_weak_dependency() {
  weak_dependency_.Clear();
}
inline ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency)
  return weak_dependency_.Get(index);
}
inline void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) {
  weak_dependency_.Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
}
inline void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) {
  weak_dependency_.Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
FileDescriptorProto::weak_dependency() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
  return weak_dependency_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
FileDescriptorProto::mutable_weak_dependency() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
  return &weak_dependency_;
}

// repeated .google.protobuf.DescriptorProto message_type = 4;
inline int FileDescriptorProto::message_type_size() const {
  return message_type_.size();
}
inline void FileDescriptorProto::clear_message_type() {
  message_type_.Clear();
}
inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
  return message_type_.Get(index);
}
inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
  return message_type_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
  return message_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
FileDescriptorProto::message_type() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
  return message_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
FileDescriptorProto::mutable_message_type() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
  return &message_type_;
}

// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
inline int FileDescriptorProto::enum_type_size() const {
  return enum_type_.size();
}
inline void FileDescriptorProto::clear_enum_type() {
  enum_type_.Clear();
}
inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
  return enum_type_.Get(index);
}
inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
  return enum_type_.Mutable(index);
}
inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
  return enum_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
FileDescriptorProto::enum_type() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
  return enum_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
FileDescriptorProto::mutable_enum_type() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
  return &enum_type_;
}

// repeated .google.protobuf.ServiceDescriptorProto service = 6;
inline int FileDescriptorProto::service_size() const {
  return service_.size();
}
inline void FileDescriptorProto::clear_service() {
  service_.Clear();
}
inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
  return service_.Get(index);
}
inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
  return service_.Mutable(index);
}
inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
  return service_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
FileDescriptorProto::service() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
  return service_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
FileDescriptorProto::mutable_service() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
  return &service_;
}

// repeated .google.protobuf.FieldDescriptorProto extension = 7;
inline int FileDescriptorProto::extension_size() const {
  return extension_.size();
}
inline void FileDescriptorProto::clear_extension() {
  extension_.Clear();
}
inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
  return extension_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
  return extension_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
  return extension_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
FileDescriptorProto::extension() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
  return extension_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
FileDescriptorProto::mutable_extension() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
  return &extension_;
}

// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void FileDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000200u;
}
inline void FileDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void FileDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
  return options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::FileOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
}

// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
inline bool FileDescriptorProto::has_source_code_info() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void FileDescriptorProto::set_has_source_code_info() {
  _has_bits_[0] |= 0x00000400u;
}
inline void FileDescriptorProto::clear_has_source_code_info() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void FileDescriptorProto::clear_source_code_info() {
  if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
  clear_has_source_code_info();
}
inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
  return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
  set_has_source_code_info();
  if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo;
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
  return source_code_info_;
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
  clear_has_source_code_info();
  ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
  source_code_info_ = NULL;
  return temp;
}
inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
  delete source_code_info_;
  source_code_info_ = source_code_info;
  if (source_code_info) {
    set_has_source_code_info();
  } else {
    clear_has_source_code_info();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
}

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

// DescriptorProto_ExtensionRange

// optional int32 start = 1;
inline bool DescriptorProto_ExtensionRange::has_start() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void DescriptorProto_ExtensionRange::set_has_start() {
  _has_bits_[0] |= 0x00000001u;
}
inline void DescriptorProto_ExtensionRange::clear_has_start() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void DescriptorProto_ExtensionRange::clear_start() {
  start_ = 0;
  clear_has_start();
}
inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
  return start_;
}
inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
  set_has_start();
  start_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
}

// optional int32 end = 2;
inline bool DescriptorProto_ExtensionRange::has_end() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void DescriptorProto_ExtensionRange::set_has_end() {
  _has_bits_[0] |= 0x00000002u;
}
inline void DescriptorProto_ExtensionRange::clear_has_end() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void DescriptorProto_ExtensionRange::clear_end() {
  end_ = 0;
  clear_has_end();
}
inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
  return end_;
}
inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
  set_has_end();
  end_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
}

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

// DescriptorProto

// optional string name = 1;
inline bool DescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void DescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void DescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void DescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& DescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
  return *name_;
}
inline void DescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
}
inline void DescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
}
inline void DescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name)
}
inline ::std::string* DescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
  return name_;
}
inline ::std::string* DescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void DescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name)
}

// repeated .google.protobuf.FieldDescriptorProto field = 2;
inline int DescriptorProto::field_size() const {
  return field_.size();
}
inline void DescriptorProto::clear_field() {
  field_.Clear();
}
inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
  return field_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
  return field_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
  return field_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
DescriptorProto::field() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
  return field_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_field() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
  return &field_;
}

// repeated .google.protobuf.FieldDescriptorProto extension = 6;
inline int DescriptorProto::extension_size() const {
  return extension_.size();
}
inline void DescriptorProto::clear_extension() {
  extension_.Clear();
}
inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
  return extension_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
  return extension_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
  return extension_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
DescriptorProto::extension() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
  return extension_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_extension() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
  return &extension_;
}

// repeated .google.protobuf.DescriptorProto nested_type = 3;
inline int DescriptorProto::nested_type_size() const {
  return nested_type_.size();
}
inline void DescriptorProto::clear_nested_type() {
  nested_type_.Clear();
}
inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
  return nested_type_.Get(index);
}
inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
  return nested_type_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
  return nested_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
DescriptorProto::nested_type() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
  return nested_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
DescriptorProto::mutable_nested_type() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
  return &nested_type_;
}

// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
inline int DescriptorProto::enum_type_size() const {
  return enum_type_.size();
}
inline void DescriptorProto::clear_enum_type() {
  enum_type_.Clear();
}
inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
  return enum_type_.Get(index);
}
inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
  return enum_type_.Mutable(index);
}
inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
  return enum_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
DescriptorProto::enum_type() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
  return enum_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
DescriptorProto::mutable_enum_type() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
  return &enum_type_;
}

// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
inline int DescriptorProto::extension_range_size() const {
  return extension_range_.size();
}
inline void DescriptorProto::clear_extension_range() {
  extension_range_.Clear();
}
inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
  return extension_range_.Get(index);
}
inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
  return extension_range_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
  return extension_range_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
DescriptorProto::extension_range() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
  return extension_range_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
DescriptorProto::mutable_extension_range() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
  return &extension_range_;
}

// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
inline int DescriptorProto::oneof_decl_size() const {
  return oneof_decl_.size();
}
inline void DescriptorProto::clear_oneof_decl() {
  oneof_decl_.Clear();
}
inline const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
  return oneof_decl_.Get(index);
}
inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
  return oneof_decl_.Mutable(index);
}
inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
  return oneof_decl_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
DescriptorProto::oneof_decl() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
  return oneof_decl_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
DescriptorProto::mutable_oneof_decl() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
  return &oneof_decl_;
}

// optional .google.protobuf.MessageOptions options = 7;
inline bool DescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void DescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000080u;
}
inline void DescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void DescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
  return options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::MessageOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
}

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

// FieldDescriptorProto

// optional string name = 1;
inline bool FieldDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FieldDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FieldDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FieldDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& FieldDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
  return *name_;
}
inline void FieldDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
}
inline void FieldDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
}
inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name)
}
inline ::std::string* FieldDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
  return name_;
}
inline ::std::string* FieldDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FieldDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
}

// optional int32 number = 3;
inline bool FieldDescriptorProto::has_number() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FieldDescriptorProto::set_has_number() {
  _has_bits_[0] |= 0x00000002u;
}
inline void FieldDescriptorProto::clear_has_number() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void FieldDescriptorProto::clear_number() {
  number_ = 0;
  clear_has_number();
}
inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
  return number_;
}
inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
  set_has_number();
  number_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
}

// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
inline bool FieldDescriptorProto::has_label() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FieldDescriptorProto::set_has_label() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FieldDescriptorProto::clear_has_label() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FieldDescriptorProto::clear_label() {
  label_ = 1;
  clear_has_label();
}
inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
  return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
}
inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
  assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
  set_has_label();
  label_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
}

// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
inline bool FieldDescriptorProto::has_type() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FieldDescriptorProto::set_has_type() {
  _has_bits_[0] |= 0x00000008u;
}
inline void FieldDescriptorProto::clear_has_type() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void FieldDescriptorProto::clear_type() {
  type_ = 1;
  clear_has_type();
}
inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
  return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
}
inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
  assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
}

// optional string type_name = 6;
inline bool FieldDescriptorProto::has_type_name() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void FieldDescriptorProto::set_has_type_name() {
  _has_bits_[0] |= 0x00000010u;
}
inline void FieldDescriptorProto::clear_has_type_name() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void FieldDescriptorProto::clear_type_name() {
  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_name_->clear();
  }
  clear_has_type_name();
}
inline const ::std::string& FieldDescriptorProto::type_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
  return *type_name_;
}
inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_name_ = new ::std::string;
  }
  type_name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
}
inline void FieldDescriptorProto::set_type_name(const char* value) {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_name_ = new ::std::string;
  }
  type_name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name)
}
inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_name_ = new ::std::string;
  }
  type_name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name)
}
inline ::std::string* FieldDescriptorProto::mutable_type_name() {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    type_name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
  return type_name_;
}
inline ::std::string* FieldDescriptorProto::release_type_name() {
  clear_has_type_name();
  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = type_name_;
    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete type_name_;
  }
  if (type_name) {
    set_has_type_name();
    type_name_ = type_name;
  } else {
    clear_has_type_name();
    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
}

// optional string extendee = 2;
inline bool FieldDescriptorProto::has_extendee() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void FieldDescriptorProto::set_has_extendee() {
  _has_bits_[0] |= 0x00000020u;
}
inline void FieldDescriptorProto::clear_has_extendee() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void FieldDescriptorProto::clear_extendee() {
  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    extendee_->clear();
  }
  clear_has_extendee();
}
inline const ::std::string& FieldDescriptorProto::extendee() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
  return *extendee_;
}
inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    extendee_ = new ::std::string;
  }
  extendee_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
}
inline void FieldDescriptorProto::set_extendee(const char* value) {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    extendee_ = new ::std::string;
  }
  extendee_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
}
inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    extendee_ = new ::std::string;
  }
  extendee_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee)
}
inline ::std::string* FieldDescriptorProto::mutable_extendee() {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    extendee_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
  return extendee_;
}
inline ::std::string* FieldDescriptorProto::release_extendee() {
  clear_has_extendee();
  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = extendee_;
    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete extendee_;
  }
  if (extendee) {
    set_has_extendee();
    extendee_ = extendee;
  } else {
    clear_has_extendee();
    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
}

// optional string default_value = 7;
inline bool FieldDescriptorProto::has_default_value() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void FieldDescriptorProto::set_has_default_value() {
  _has_bits_[0] |= 0x00000040u;
}
inline void FieldDescriptorProto::clear_has_default_value() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void FieldDescriptorProto::clear_default_value() {
  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    default_value_->clear();
  }
  clear_has_default_value();
}
inline const ::std::string& FieldDescriptorProto::default_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
  return *default_value_;
}
inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    default_value_ = new ::std::string;
  }
  default_value_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
}
inline void FieldDescriptorProto::set_default_value(const char* value) {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    default_value_ = new ::std::string;
  }
  default_value_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value)
}
inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    default_value_ = new ::std::string;
  }
  default_value_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value)
}
inline ::std::string* FieldDescriptorProto::mutable_default_value() {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    default_value_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
  return default_value_;
}
inline ::std::string* FieldDescriptorProto::release_default_value() {
  clear_has_default_value();
  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = default_value_;
    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete default_value_;
  }
  if (default_value) {
    set_has_default_value();
    default_value_ = default_value;
  } else {
    clear_has_default_value();
    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
}

// optional int32 oneof_index = 9;
inline bool FieldDescriptorProto::has_oneof_index() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void FieldDescriptorProto::set_has_oneof_index() {
  _has_bits_[0] |= 0x00000080u;
}
inline void FieldDescriptorProto::clear_has_oneof_index() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void FieldDescriptorProto::clear_oneof_index() {
  oneof_index_ = 0;
  clear_has_oneof_index();
}
inline ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
  return oneof_index_;
}
inline void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) {
  set_has_oneof_index();
  oneof_index_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
}

// optional .google.protobuf.FieldOptions options = 8;
inline bool FieldDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void FieldDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000100u;
}
inline void FieldDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void FieldDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
  return options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::FieldOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
}

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

// OneofDescriptorProto

// optional string name = 1;
inline bool OneofDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void OneofDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void OneofDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void OneofDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& OneofDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
  return *name_;
}
inline void OneofDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
}
inline void OneofDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
}
inline void OneofDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name)
}
inline ::std::string* OneofDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
  return name_;
}
inline ::std::string* OneofDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void OneofDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
}

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

// EnumDescriptorProto

// optional string name = 1;
inline bool EnumDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void EnumDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void EnumDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void EnumDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& EnumDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
  return *name_;
}
inline void EnumDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
}
inline void EnumDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
}
inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name)
}
inline ::std::string* EnumDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
  return name_;
}
inline ::std::string* EnumDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void EnumDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name)
}

// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
inline int EnumDescriptorProto::value_size() const {
  return value_.size();
}
inline void EnumDescriptorProto::clear_value() {
  value_.Clear();
}
inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
  return value_.Get(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
  return value_.Mutable(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
  return value_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
EnumDescriptorProto::value() const {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
  return value_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
EnumDescriptorProto::mutable_value() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
  return &value_;
}

// optional .google.protobuf.EnumOptions options = 3;
inline bool EnumDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void EnumDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000004u;
}
inline void EnumDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void EnumDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
  return options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::EnumOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
}

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

// EnumValueDescriptorProto

// optional string name = 1;
inline bool EnumValueDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void EnumValueDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void EnumValueDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void EnumValueDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& EnumValueDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
  return *name_;
}
inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
}
inline void EnumValueDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
}
inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name)
}
inline ::std::string* EnumValueDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
  return name_;
}
inline ::std::string* EnumValueDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
}

// optional int32 number = 2;
inline bool EnumValueDescriptorProto::has_number() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void EnumValueDescriptorProto::set_has_number() {
  _has_bits_[0] |= 0x00000002u;
}
inline void EnumValueDescriptorProto::clear_has_number() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void EnumValueDescriptorProto::clear_number() {
  number_ = 0;
  clear_has_number();
}
inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
  return number_;
}
inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
  set_has_number();
  number_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
}

// optional .google.protobuf.EnumValueOptions options = 3;
inline bool EnumValueDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void EnumValueDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000004u;
}
inline void EnumValueDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void EnumValueDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
  return options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::EnumValueOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
}

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

// ServiceDescriptorProto

// optional string name = 1;
inline bool ServiceDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void ServiceDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void ServiceDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void ServiceDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& ServiceDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
  return *name_;
}
inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
}
inline void ServiceDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
}
inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name)
}
inline ::std::string* ServiceDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
  return name_;
}
inline ::std::string* ServiceDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name)
}

// repeated .google.protobuf.MethodDescriptorProto method = 2;
inline int ServiceDescriptorProto::method_size() const {
  return method_.size();
}
inline void ServiceDescriptorProto::clear_method() {
  method_.Clear();
}
inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
  return method_.Get(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
  return method_.Mutable(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
  // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
  return method_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
ServiceDescriptorProto::method() const {
  // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
  return method_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
ServiceDescriptorProto::mutable_method() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
  return &method_;
}

// optional .google.protobuf.ServiceOptions options = 3;
inline bool ServiceDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void ServiceDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000004u;
}
inline void ServiceDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void ServiceDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
  return options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::ServiceOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
}

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

// MethodDescriptorProto

// optional string name = 1;
inline bool MethodDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MethodDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MethodDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MethodDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& MethodDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
  return *name_;
}
inline void MethodDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
}
inline void MethodDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
}
inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name)
}
inline ::std::string* MethodDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
  return name_;
}
inline ::std::string* MethodDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MethodDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
}

// optional string input_type = 2;
inline bool MethodDescriptorProto::has_input_type() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MethodDescriptorProto::set_has_input_type() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MethodDescriptorProto::clear_has_input_type() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MethodDescriptorProto::clear_input_type() {
  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    input_type_->clear();
  }
  clear_has_input_type();
}
inline const ::std::string& MethodDescriptorProto::input_type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
  return *input_type_;
}
inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    input_type_ = new ::std::string;
  }
  input_type_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
}
inline void MethodDescriptorProto::set_input_type(const char* value) {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    input_type_ = new ::std::string;
  }
  input_type_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type)
}
inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    input_type_ = new ::std::string;
  }
  input_type_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type)
}
inline ::std::string* MethodDescriptorProto::mutable_input_type() {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    input_type_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
  return input_type_;
}
inline ::std::string* MethodDescriptorProto::release_input_type() {
  clear_has_input_type();
  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = input_type_;
    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete input_type_;
  }
  if (input_type) {
    set_has_input_type();
    input_type_ = input_type;
  } else {
    clear_has_input_type();
    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
}

// optional string output_type = 3;
inline bool MethodDescriptorProto::has_output_type() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MethodDescriptorProto::set_has_output_type() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MethodDescriptorProto::clear_has_output_type() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MethodDescriptorProto::clear_output_type() {
  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    output_type_->clear();
  }
  clear_has_output_type();
}
inline const ::std::string& MethodDescriptorProto::output_type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
  return *output_type_;
}
inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    output_type_ = new ::std::string;
  }
  output_type_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
}
inline void MethodDescriptorProto::set_output_type(const char* value) {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    output_type_ = new ::std::string;
  }
  output_type_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type)
}
inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    output_type_ = new ::std::string;
  }
  output_type_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type)
}
inline ::std::string* MethodDescriptorProto::mutable_output_type() {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    output_type_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
  return output_type_;
}
inline ::std::string* MethodDescriptorProto::release_output_type() {
  clear_has_output_type();
  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = output_type_;
    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete output_type_;
  }
  if (output_type) {
    set_has_output_type();
    output_type_ = output_type;
  } else {
    clear_has_output_type();
    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
}

// optional .google.protobuf.MethodOptions options = 4;
inline bool MethodDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MethodDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MethodDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MethodDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
  return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
  set_has_options();
  if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
  return options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::MethodOptions* temp = options_;
  options_ = NULL;
  return temp;
}
inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
}

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

// FileOptions

// optional string java_package = 1;
inline bool FileOptions::has_java_package() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FileOptions::set_has_java_package() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FileOptions::clear_has_java_package() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FileOptions::clear_java_package() {
  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_package_->clear();
  }
  clear_has_java_package();
}
inline const ::std::string& FileOptions::java_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
  return *java_package_;
}
inline void FileOptions::set_java_package(const ::std::string& value) {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_package_ = new ::std::string;
  }
  java_package_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
}
inline void FileOptions::set_java_package(const char* value) {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_package_ = new ::std::string;
  }
  java_package_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
}
inline void FileOptions::set_java_package(const char* value, size_t size) {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_package_ = new ::std::string;
  }
  java_package_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
}
inline ::std::string* FileOptions::mutable_java_package() {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_package_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
  return java_package_;
}
inline ::std::string* FileOptions::release_java_package() {
  clear_has_java_package();
  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = java_package_;
    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete java_package_;
  }
  if (java_package) {
    set_has_java_package();
    java_package_ = java_package;
  } else {
    clear_has_java_package();
    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
}

// optional string java_outer_classname = 8;
inline bool FileOptions::has_java_outer_classname() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FileOptions::set_has_java_outer_classname() {
  _has_bits_[0] |= 0x00000002u;
}
inline void FileOptions::clear_has_java_outer_classname() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void FileOptions::clear_java_outer_classname() {
  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_outer_classname_->clear();
  }
  clear_has_java_outer_classname();
}
inline const ::std::string& FileOptions::java_outer_classname() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
  return *java_outer_classname_;
}
inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
  set_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_outer_classname_ = new ::std::string;
  }
  java_outer_classname_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
}
inline void FileOptions::set_java_outer_classname(const char* value) {
  set_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_outer_classname_ = new ::std::string;
  }
  java_outer_classname_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname)
}
inline void FileOptions::set_java_outer_classname(const char* value, size_t size) {
  set_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_outer_classname_ = new ::std::string;
  }
  java_outer_classname_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname)
}
inline ::std::string* FileOptions::mutable_java_outer_classname() {
  set_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    java_outer_classname_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
  return java_outer_classname_;
}
inline ::std::string* FileOptions::release_java_outer_classname() {
  clear_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = java_outer_classname_;
    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete java_outer_classname_;
  }
  if (java_outer_classname) {
    set_has_java_outer_classname();
    java_outer_classname_ = java_outer_classname;
  } else {
    clear_has_java_outer_classname();
    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
}

// optional bool java_multiple_files = 10 [default = false];
inline bool FileOptions::has_java_multiple_files() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FileOptions::set_has_java_multiple_files() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FileOptions::clear_has_java_multiple_files() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FileOptions::clear_java_multiple_files() {
  java_multiple_files_ = false;
  clear_has_java_multiple_files();
}
inline bool FileOptions::java_multiple_files() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
  return java_multiple_files_;
}
inline void FileOptions::set_java_multiple_files(bool value) {
  set_has_java_multiple_files();
  java_multiple_files_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
}

// optional bool java_generate_equals_and_hash = 20 [default = false];
inline bool FileOptions::has_java_generate_equals_and_hash() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FileOptions::set_has_java_generate_equals_and_hash() {
  _has_bits_[0] |= 0x00000008u;
}
inline void FileOptions::clear_has_java_generate_equals_and_hash() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void FileOptions::clear_java_generate_equals_and_hash() {
  java_generate_equals_and_hash_ = false;
  clear_has_java_generate_equals_and_hash();
}
inline bool FileOptions::java_generate_equals_and_hash() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
  return java_generate_equals_and_hash_;
}
inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
  set_has_java_generate_equals_and_hash();
  java_generate_equals_and_hash_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
}

// optional bool java_string_check_utf8 = 27 [default = false];
inline bool FileOptions::has_java_string_check_utf8() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void FileOptions::set_has_java_string_check_utf8() {
  _has_bits_[0] |= 0x00000010u;
}
inline void FileOptions::clear_has_java_string_check_utf8() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void FileOptions::clear_java_string_check_utf8() {
  java_string_check_utf8_ = false;
  clear_has_java_string_check_utf8();
}
inline bool FileOptions::java_string_check_utf8() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
  return java_string_check_utf8_;
}
inline void FileOptions::set_java_string_check_utf8(bool value) {
  set_has_java_string_check_utf8();
  java_string_check_utf8_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
}

// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
inline bool FileOptions::has_optimize_for() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void FileOptions::set_has_optimize_for() {
  _has_bits_[0] |= 0x00000020u;
}
inline void FileOptions::clear_has_optimize_for() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void FileOptions::clear_optimize_for() {
  optimize_for_ = 1;
  clear_has_optimize_for();
}
inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
  return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
}
inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
  assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
  set_has_optimize_for();
  optimize_for_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
}

// optional string go_package = 11;
inline bool FileOptions::has_go_package() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void FileOptions::set_has_go_package() {
  _has_bits_[0] |= 0x00000040u;
}
inline void FileOptions::clear_has_go_package() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void FileOptions::clear_go_package() {
  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    go_package_->clear();
  }
  clear_has_go_package();
}
inline const ::std::string& FileOptions::go_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
  return *go_package_;
}
inline void FileOptions::set_go_package(const ::std::string& value) {
  set_has_go_package();
  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    go_package_ = new ::std::string;
  }
  go_package_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
}
inline void FileOptions::set_go_package(const char* value) {
  set_has_go_package();
  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    go_package_ = new ::std::string;
  }
  go_package_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package)
}
inline void FileOptions::set_go_package(const char* value, size_t size) {
  set_has_go_package();
  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    go_package_ = new ::std::string;
  }
  go_package_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package)
}
inline ::std::string* FileOptions::mutable_go_package() {
  set_has_go_package();
  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    go_package_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
  return go_package_;
}
inline ::std::string* FileOptions::release_go_package() {
  clear_has_go_package();
  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = go_package_;
    go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FileOptions::set_allocated_go_package(::std::string* go_package) {
  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete go_package_;
  }
  if (go_package) {
    set_has_go_package();
    go_package_ = go_package;
  } else {
    clear_has_go_package();
    go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
}

// optional bool cc_generic_services = 16 [default = false];
inline bool FileOptions::has_cc_generic_services() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void FileOptions::set_has_cc_generic_services() {
  _has_bits_[0] |= 0x00000080u;
}
inline void FileOptions::clear_has_cc_generic_services() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void FileOptions::clear_cc_generic_services() {
  cc_generic_services_ = false;
  clear_has_cc_generic_services();
}
inline bool FileOptions::cc_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
  return cc_generic_services_;
}
inline void FileOptions::set_cc_generic_services(bool value) {
  set_has_cc_generic_services();
  cc_generic_services_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
}

// optional bool java_generic_services = 17 [default = false];
inline bool FileOptions::has_java_generic_services() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void FileOptions::set_has_java_generic_services() {
  _has_bits_[0] |= 0x00000100u;
}
inline void FileOptions::clear_has_java_generic_services() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void FileOptions::clear_java_generic_services() {
  java_generic_services_ = false;
  clear_has_java_generic_services();
}
inline bool FileOptions::java_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
  return java_generic_services_;
}
inline void FileOptions::set_java_generic_services(bool value) {
  set_has_java_generic_services();
  java_generic_services_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
}

// optional bool py_generic_services = 18 [default = false];
inline bool FileOptions::has_py_generic_services() const {
  return (_has_bits_[0] & 0x00000200u) != 0;
}
inline void FileOptions::set_has_py_generic_services() {
  _has_bits_[0] |= 0x00000200u;
}
inline void FileOptions::clear_has_py_generic_services() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void FileOptions::clear_py_generic_services() {
  py_generic_services_ = false;
  clear_has_py_generic_services();
}
inline bool FileOptions::py_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
  return py_generic_services_;
}
inline void FileOptions::set_py_generic_services(bool value) {
  set_has_py_generic_services();
  py_generic_services_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
}

// optional bool deprecated = 23 [default = false];
inline bool FileOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void FileOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000400u;
}
inline void FileOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void FileOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool FileOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
  return deprecated_;
}
inline void FileOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
}

// optional bool javanano_use_deprecated_package = 38;
inline bool FileOptions::has_javanano_use_deprecated_package() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void FileOptions::set_has_javanano_use_deprecated_package() {
  _has_bits_[0] |= 0x00000800u;
}
inline void FileOptions::clear_has_javanano_use_deprecated_package() {
  _has_bits_[0] &= ~0x00000800u;
}
inline void FileOptions::clear_javanano_use_deprecated_package() {
  javanano_use_deprecated_package_ = false;
  clear_has_javanano_use_deprecated_package();
}
inline bool FileOptions::javanano_use_deprecated_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.javanano_use_deprecated_package)
  return javanano_use_deprecated_package_;
}
inline void FileOptions::set_javanano_use_deprecated_package(bool value) {
  set_has_javanano_use_deprecated_package();
  javanano_use_deprecated_package_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.javanano_use_deprecated_package)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FileOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void FileOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
FileOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FileOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// MessageOptions

// optional bool message_set_wire_format = 1 [default = false];
inline bool MessageOptions::has_message_set_wire_format() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageOptions::set_has_message_set_wire_format() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageOptions::clear_has_message_set_wire_format() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageOptions::clear_message_set_wire_format() {
  message_set_wire_format_ = false;
  clear_has_message_set_wire_format();
}
inline bool MessageOptions::message_set_wire_format() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
  return message_set_wire_format_;
}
inline void MessageOptions::set_message_set_wire_format(bool value) {
  set_has_message_set_wire_format();
  message_set_wire_format_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
}

// optional bool no_standard_descriptor_accessor = 2 [default = false];
inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageOptions::clear_no_standard_descriptor_accessor() {
  no_standard_descriptor_accessor_ = false;
  clear_has_no_standard_descriptor_accessor();
}
inline bool MessageOptions::no_standard_descriptor_accessor() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
  return no_standard_descriptor_accessor_;
}
inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
  set_has_no_standard_descriptor_accessor();
  no_standard_descriptor_accessor_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
}

// optional bool deprecated = 3 [default = false];
inline bool MessageOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MessageOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MessageOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MessageOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool MessageOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
  return deprecated_;
}
inline void MessageOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int MessageOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void MessageOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
MessageOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MessageOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// FieldOptions

// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
inline bool FieldOptions::has_ctype() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FieldOptions::set_has_ctype() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FieldOptions::clear_has_ctype() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FieldOptions::clear_ctype() {
  ctype_ = 0;
  clear_has_ctype();
}
inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
  return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
}
inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
  assert(::google::protobuf::FieldOptions_CType_IsValid(value));
  set_has_ctype();
  ctype_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
}

// optional bool packed = 2;
inline bool FieldOptions::has_packed() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FieldOptions::set_has_packed() {
  _has_bits_[0] |= 0x00000002u;
}
inline void FieldOptions::clear_has_packed() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void FieldOptions::clear_packed() {
  packed_ = false;
  clear_has_packed();
}
inline bool FieldOptions::packed() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
  return packed_;
}
inline void FieldOptions::set_packed(bool value) {
  set_has_packed();
  packed_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
}

// optional bool lazy = 5 [default = false];
inline bool FieldOptions::has_lazy() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FieldOptions::set_has_lazy() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FieldOptions::clear_has_lazy() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FieldOptions::clear_lazy() {
  lazy_ = false;
  clear_has_lazy();
}
inline bool FieldOptions::lazy() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
  return lazy_;
}
inline void FieldOptions::set_lazy(bool value) {
  set_has_lazy();
  lazy_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
}

// optional bool deprecated = 3 [default = false];
inline bool FieldOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FieldOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000008u;
}
inline void FieldOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void FieldOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool FieldOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
  return deprecated_;
}
inline void FieldOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
}

// optional string experimental_map_key = 9;
inline bool FieldOptions::has_experimental_map_key() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void FieldOptions::set_has_experimental_map_key() {
  _has_bits_[0] |= 0x00000010u;
}
inline void FieldOptions::clear_has_experimental_map_key() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void FieldOptions::clear_experimental_map_key() {
  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    experimental_map_key_->clear();
  }
  clear_has_experimental_map_key();
}
inline const ::std::string& FieldOptions::experimental_map_key() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.experimental_map_key)
  return *experimental_map_key_;
}
inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
  set_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    experimental_map_key_ = new ::std::string;
  }
  experimental_map_key_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.experimental_map_key)
}
inline void FieldOptions::set_experimental_map_key(const char* value) {
  set_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    experimental_map_key_ = new ::std::string;
  }
  experimental_map_key_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldOptions.experimental_map_key)
}
inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) {
  set_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    experimental_map_key_ = new ::std::string;
  }
  experimental_map_key_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldOptions.experimental_map_key)
}
inline ::std::string* FieldOptions::mutable_experimental_map_key() {
  set_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    experimental_map_key_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.experimental_map_key)
  return experimental_map_key_;
}
inline ::std::string* FieldOptions::release_experimental_map_key() {
  clear_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = experimental_map_key_;
    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void FieldOptions::set_allocated_experimental_map_key(::std::string* experimental_map_key) {
  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete experimental_map_key_;
  }
  if (experimental_map_key) {
    set_has_experimental_map_key();
    experimental_map_key_ = experimental_map_key;
  } else {
    clear_has_experimental_map_key();
    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.experimental_map_key)
}

// optional bool weak = 10 [default = false];
inline bool FieldOptions::has_weak() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void FieldOptions::set_has_weak() {
  _has_bits_[0] |= 0x00000020u;
}
inline void FieldOptions::clear_has_weak() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void FieldOptions::clear_weak() {
  weak_ = false;
  clear_has_weak();
}
inline bool FieldOptions::weak() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
  return weak_;
}
inline void FieldOptions::set_weak(bool value) {
  set_has_weak();
  weak_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FieldOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void FieldOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
FieldOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FieldOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// EnumOptions

// optional bool allow_alias = 2;
inline bool EnumOptions::has_allow_alias() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void EnumOptions::set_has_allow_alias() {
  _has_bits_[0] |= 0x00000001u;
}
inline void EnumOptions::clear_has_allow_alias() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void EnumOptions::clear_allow_alias() {
  allow_alias_ = false;
  clear_has_allow_alias();
}
inline bool EnumOptions::allow_alias() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
  return allow_alias_;
}
inline void EnumOptions::set_allow_alias(bool value) {
  set_has_allow_alias();
  allow_alias_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
}

// optional bool deprecated = 3 [default = false];
inline bool EnumOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void EnumOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000002u;
}
inline void EnumOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void EnumOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool EnumOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
  return deprecated_;
}
inline void EnumOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int EnumOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void EnumOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
EnumOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// EnumValueOptions

// optional bool deprecated = 1 [default = false];
inline bool EnumValueOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void EnumValueOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000001u;
}
inline void EnumValueOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void EnumValueOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool EnumValueOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
  return deprecated_;
}
inline void EnumValueOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int EnumValueOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void EnumValueOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
EnumValueOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumValueOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// ServiceOptions

// optional bool deprecated = 33 [default = false];
inline bool ServiceOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void ServiceOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000001u;
}
inline void ServiceOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void ServiceOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool ServiceOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
  return deprecated_;
}
inline void ServiceOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int ServiceOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void ServiceOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
ServiceOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
ServiceOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// MethodOptions

// optional bool deprecated = 33 [default = false];
inline bool MethodOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MethodOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MethodOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MethodOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool MethodOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
  return deprecated_;
}
inline void MethodOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int MethodOptions::uninterpreted_option_size() const {
  return uninterpreted_option_.size();
}
inline void MethodOptions::clear_uninterpreted_option() {
  uninterpreted_option_.Clear();
}
inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
  // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
MethodOptions::uninterpreted_option() const {
  // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MethodOptions::mutable_uninterpreted_option() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
  return &uninterpreted_option_;
}

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

// UninterpretedOption_NamePart

// required string name_part = 1;
inline bool UninterpretedOption_NamePart::has_name_part() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void UninterpretedOption_NamePart::set_has_name_part() {
  _has_bits_[0] |= 0x00000001u;
}
inline void UninterpretedOption_NamePart::clear_has_name_part() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void UninterpretedOption_NamePart::clear_name_part() {
  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_part_->clear();
  }
  clear_has_name_part();
}
inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
  return *name_part_;
}
inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_part_ = new ::std::string;
  }
  name_part_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_part_ = new ::std::string;
  }
  name_part_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_part_ = new ::std::string;
  }
  name_part_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_part_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
  return name_part_;
}
inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
  clear_has_name_part();
  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_part_;
    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_part_;
  }
  if (name_part) {
    set_has_name_part();
    name_part_ = name_part;
  } else {
    clear_has_name_part();
    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
}

// required bool is_extension = 2;
inline bool UninterpretedOption_NamePart::has_is_extension() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void UninterpretedOption_NamePart::set_has_is_extension() {
  _has_bits_[0] |= 0x00000002u;
}
inline void UninterpretedOption_NamePart::clear_has_is_extension() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void UninterpretedOption_NamePart::clear_is_extension() {
  is_extension_ = false;
  clear_has_is_extension();
}
inline bool UninterpretedOption_NamePart::is_extension() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
  return is_extension_;
}
inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
  set_has_is_extension();
  is_extension_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
}

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

// UninterpretedOption

// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
inline int UninterpretedOption::name_size() const {
  return name_.size();
}
inline void UninterpretedOption::clear_name() {
  name_.Clear();
}
inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
  return name_.Get(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
  return name_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
  // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
  return name_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
UninterpretedOption::name() const {
  // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
  return name_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
UninterpretedOption::mutable_name() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
  return &name_;
}

// optional string identifier_value = 3;
inline bool UninterpretedOption::has_identifier_value() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void UninterpretedOption::set_has_identifier_value() {
  _has_bits_[0] |= 0x00000002u;
}
inline void UninterpretedOption::clear_has_identifier_value() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void UninterpretedOption::clear_identifier_value() {
  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    identifier_value_->clear();
  }
  clear_has_identifier_value();
}
inline const ::std::string& UninterpretedOption::identifier_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
  return *identifier_value_;
}
inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    identifier_value_ = new ::std::string;
  }
  identifier_value_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
}
inline void UninterpretedOption::set_identifier_value(const char* value) {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    identifier_value_ = new ::std::string;
  }
  identifier_value_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value)
}
inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    identifier_value_ = new ::std::string;
  }
  identifier_value_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value)
}
inline ::std::string* UninterpretedOption::mutable_identifier_value() {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    identifier_value_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
  return identifier_value_;
}
inline ::std::string* UninterpretedOption::release_identifier_value() {
  clear_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = identifier_value_;
    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete identifier_value_;
  }
  if (identifier_value) {
    set_has_identifier_value();
    identifier_value_ = identifier_value;
  } else {
    clear_has_identifier_value();
    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
}

// optional uint64 positive_int_value = 4;
inline bool UninterpretedOption::has_positive_int_value() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void UninterpretedOption::set_has_positive_int_value() {
  _has_bits_[0] |= 0x00000004u;
}
inline void UninterpretedOption::clear_has_positive_int_value() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void UninterpretedOption::clear_positive_int_value() {
  positive_int_value_ = GOOGLE_ULONGLONG(0);
  clear_has_positive_int_value();
}
inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
  return positive_int_value_;
}
inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
  set_has_positive_int_value();
  positive_int_value_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
}

// optional int64 negative_int_value = 5;
inline bool UninterpretedOption::has_negative_int_value() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void UninterpretedOption::set_has_negative_int_value() {
  _has_bits_[0] |= 0x00000008u;
}
inline void UninterpretedOption::clear_has_negative_int_value() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void UninterpretedOption::clear_negative_int_value() {
  negative_int_value_ = GOOGLE_LONGLONG(0);
  clear_has_negative_int_value();
}
inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
  return negative_int_value_;
}
inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
  set_has_negative_int_value();
  negative_int_value_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
}

// optional double double_value = 6;
inline bool UninterpretedOption::has_double_value() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void UninterpretedOption::set_has_double_value() {
  _has_bits_[0] |= 0x00000010u;
}
inline void UninterpretedOption::clear_has_double_value() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void UninterpretedOption::clear_double_value() {
  double_value_ = 0;
  clear_has_double_value();
}
inline double UninterpretedOption::double_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
  return double_value_;
}
inline void UninterpretedOption::set_double_value(double value) {
  set_has_double_value();
  double_value_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
}

// optional bytes string_value = 7;
inline bool UninterpretedOption::has_string_value() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void UninterpretedOption::set_has_string_value() {
  _has_bits_[0] |= 0x00000020u;
}
inline void UninterpretedOption::clear_has_string_value() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void UninterpretedOption::clear_string_value() {
  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    string_value_->clear();
  }
  clear_has_string_value();
}
inline const ::std::string& UninterpretedOption::string_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
  return *string_value_;
}
inline void UninterpretedOption::set_string_value(const ::std::string& value) {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    string_value_ = new ::std::string;
  }
  string_value_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
}
inline void UninterpretedOption::set_string_value(const char* value) {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    string_value_ = new ::std::string;
  }
  string_value_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value)
}
inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    string_value_ = new ::std::string;
  }
  string_value_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value)
}
inline ::std::string* UninterpretedOption::mutable_string_value() {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    string_value_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
  return string_value_;
}
inline ::std::string* UninterpretedOption::release_string_value() {
  clear_has_string_value();
  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = string_value_;
    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete string_value_;
  }
  if (string_value) {
    set_has_string_value();
    string_value_ = string_value;
  } else {
    clear_has_string_value();
    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
}

// optional string aggregate_value = 8;
inline bool UninterpretedOption::has_aggregate_value() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void UninterpretedOption::set_has_aggregate_value() {
  _has_bits_[0] |= 0x00000040u;
}
inline void UninterpretedOption::clear_has_aggregate_value() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void UninterpretedOption::clear_aggregate_value() {
  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    aggregate_value_->clear();
  }
  clear_has_aggregate_value();
}
inline const ::std::string& UninterpretedOption::aggregate_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
  return *aggregate_value_;
}
inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    aggregate_value_ = new ::std::string;
  }
  aggregate_value_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
}
inline void UninterpretedOption::set_aggregate_value(const char* value) {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    aggregate_value_ = new ::std::string;
  }
  aggregate_value_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value)
}
inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    aggregate_value_ = new ::std::string;
  }
  aggregate_value_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value)
}
inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    aggregate_value_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
  return aggregate_value_;
}
inline ::std::string* UninterpretedOption::release_aggregate_value() {
  clear_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = aggregate_value_;
    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete aggregate_value_;
  }
  if (aggregate_value) {
    set_has_aggregate_value();
    aggregate_value_ = aggregate_value;
  } else {
    clear_has_aggregate_value();
    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
}

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

// SourceCodeInfo_Location

// repeated int32 path = 1 [packed = true];
inline int SourceCodeInfo_Location::path_size() const {
  return path_.size();
}
inline void SourceCodeInfo_Location::clear_path() {
  path_.Clear();
}
inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path)
  return path_.Get(index);
}
inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
  path_.Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
}
inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
  path_.Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
SourceCodeInfo_Location::path() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
  return path_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
SourceCodeInfo_Location::mutable_path() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path)
  return &path_;
}

// repeated int32 span = 2 [packed = true];
inline int SourceCodeInfo_Location::span_size() const {
  return span_.size();
}
inline void SourceCodeInfo_Location::clear_span() {
  span_.Clear();
}
inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span)
  return span_.Get(index);
}
inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
  span_.Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
}
inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
  span_.Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
SourceCodeInfo_Location::span() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
  return span_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
SourceCodeInfo_Location::mutable_span() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span)
  return &span_;
}

// optional string leading_comments = 3;
inline bool SourceCodeInfo_Location::has_leading_comments() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void SourceCodeInfo_Location::set_has_leading_comments() {
  _has_bits_[0] |= 0x00000004u;
}
inline void SourceCodeInfo_Location::clear_has_leading_comments() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void SourceCodeInfo_Location::clear_leading_comments() {
  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    leading_comments_->clear();
  }
  clear_has_leading_comments();
}
inline const ::std::string& SourceCodeInfo_Location::leading_comments() const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
  return *leading_comments_;
}
inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) {
  set_has_leading_comments();
  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    leading_comments_ = new ::std::string;
  }
  leading_comments_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
}
inline void SourceCodeInfo_Location::set_leading_comments(const char* value) {
  set_has_leading_comments();
  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    leading_comments_ = new ::std::string;
  }
  leading_comments_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments)
}
inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) {
  set_has_leading_comments();
  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    leading_comments_ = new ::std::string;
  }
  leading_comments_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments)
}
inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
  set_has_leading_comments();
  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    leading_comments_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
  return leading_comments_;
}
inline ::std::string* SourceCodeInfo_Location::release_leading_comments() {
  clear_has_leading_comments();
  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = leading_comments_;
    leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) {
  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete leading_comments_;
  }
  if (leading_comments) {
    set_has_leading_comments();
    leading_comments_ = leading_comments;
  } else {
    clear_has_leading_comments();
    leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
}

// optional string trailing_comments = 4;
inline bool SourceCodeInfo_Location::has_trailing_comments() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void SourceCodeInfo_Location::set_has_trailing_comments() {
  _has_bits_[0] |= 0x00000008u;
}
inline void SourceCodeInfo_Location::clear_has_trailing_comments() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void SourceCodeInfo_Location::clear_trailing_comments() {
  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    trailing_comments_->clear();
  }
  clear_has_trailing_comments();
}
inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
  return *trailing_comments_;
}
inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) {
  set_has_trailing_comments();
  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    trailing_comments_ = new ::std::string;
  }
  trailing_comments_->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}
inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
  set_has_trailing_comments();
  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    trailing_comments_ = new ::std::string;
  }
  trailing_comments_->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}
inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) {
  set_has_trailing_comments();
  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    trailing_comments_ = new ::std::string;
  }
  trailing_comments_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}
inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
  set_has_trailing_comments();
  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    trailing_comments_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
  return trailing_comments_;
}
inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() {
  clear_has_trailing_comments();
  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = trailing_comments_;
    trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) {
  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete trailing_comments_;
  }
  if (trailing_comments) {
    set_has_trailing_comments();
    trailing_comments_ = trailing_comments;
  } else {
    clear_has_trailing_comments();
    trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}

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

// SourceCodeInfo

// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
inline int SourceCodeInfo::location_size() const {
  return location_.size();
}
inline void SourceCodeInfo::clear_location() {
  location_.Clear();
}
inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
  return location_.Get(index);
}
inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
  return location_.Mutable(index);
}
inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
  return location_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
SourceCodeInfo::location() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
  return location_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
SourceCodeInfo::mutable_location() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
  return &location_;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

#ifndef SWIG
namespace google {
namespace protobuf {

template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Type> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() {
  return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
}
template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Label> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() {
  return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
}
template <> struct is_proto_enum< ::google::protobuf::FileOptions_OptimizeMode> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() {
  return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
}
template <> struct is_proto_enum< ::google::protobuf::FieldOptions_CType> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() {
  return ::google::protobuf::FieldOptions_CType_descriptor();
}

}  // namespace google
}  // namespace protobuf
#endif  // SWIG

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
