// 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 < 2003000
#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 2003001 < 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/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_reflection.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 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::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
  
  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();
  
  // 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();
  
  // 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 .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();
  
  // 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();
  
  // @@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_;
  
  ::std::string* name_;
  ::std::string* package_;
  ::google::protobuf::RepeatedPtrField< ::std::string> 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_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
  
  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::int32 start_;
  ::google::protobuf::int32 end_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
  
  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();
  
  // 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();
  
  // 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();
  
  // @@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_;
  
  ::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::MessageOptions* options_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
  
  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();
  
  // 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();
  
  // 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();
  
  // 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();
  
  // 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();
  
  // @@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_options();
  inline void clear_has_options();
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::std::string* name_;
  ::google::protobuf::int32 number_;
  int label_;
  ::std::string* type_name_;
  ::std::string* extendee_;
  ::std::string* default_value_;
  ::google::protobuf::FieldOptions* options_;
  int type_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
  
  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 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();
  
  // 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();
  
  // @@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_;
  
  ::std::string* name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
  ::google::protobuf::EnumOptions* options_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
  
  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();
  
  // 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();
  
  // @@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_;
  
  ::std::string* name_;
  ::google::protobuf::EnumValueOptions* options_;
  ::google::protobuf::int32 number_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
  
  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();
  
  // 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();
  
  // @@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_;
  
  ::std::string* name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
  ::google::protobuf::ServiceOptions* options_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
  
  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();
  
  // 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();
  
  // 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();
  
  // 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();
  
  // @@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_;
  
  ::std::string* name_;
  ::std::string* input_type_;
  ::std::string* output_type_;
  ::google::protobuf::MethodOptions* options_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
  
  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();
  
  // 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();
  
  // 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 .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 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);
  
  // 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_optimize_for();
  inline void clear_has_optimize_for();
  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();
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::std::string* java_package_;
  ::std::string* java_outer_classname_;
  int optimize_for_;
  bool java_multiple_files_;
  bool java_generate_equals_and_hash_;
  bool cc_generic_services_;
  bool java_generic_services_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool py_generic_services_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
  
  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);
  
  // 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();
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool message_set_wire_format_;
  bool no_standard_descriptor_accessor_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
  
  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 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();
  
  // 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_deprecated();
  inline void clear_has_deprecated();
  inline void set_has_experimental_map_key();
  inline void clear_has_experimental_map_key();
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  int ctype_;
  bool packed_;
  bool deprecated_;
  ::std::string* experimental_map_key_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32];
  
  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 -------------------------------------------------------
  
  // 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:
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
  
  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 -------------------------------------------------------
  
  // 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:
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
  
  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 -------------------------------------------------------
  
  // 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:
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
  
  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 -------------------------------------------------------
  
  // 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:
  
  ::google::protobuf::internal::ExtensionSet _extensions_;
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
  
  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();
  
  // 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_;
  
  ::std::string* name_part_;
  bool is_extension_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
  
  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();
  
  // 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();
  
  // 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();
  
  // @@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::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_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
  
  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();
  
  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
 private:
  
  ::google::protobuf::UnknownFieldSet _unknown_fields_;
  
  ::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_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
  
  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::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
  
  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
  
  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 {
  return file_.Get(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
  return file_.Mutable(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
  return file_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
FileDescriptorSet::file() const {
  return file_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
FileDescriptorSet::mutable_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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& FileDescriptorProto::name() const {
  return *name_;
}
inline void FileDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void FileDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void FileDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* FileDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    package_->clear();
  }
  clear_has_package();
}
inline const ::std::string& FileDescriptorProto::package() const {
  return *package_;
}
inline void FileDescriptorProto::set_package(const ::std::string& value) {
  set_has_package();
  if (package_ == &::google::protobuf::internal::kEmptyString) {
    package_ = new ::std::string;
  }
  package_->assign(value);
}
inline void FileDescriptorProto::set_package(const char* value) {
  set_has_package();
  if (package_ == &::google::protobuf::internal::kEmptyString) {
    package_ = new ::std::string;
  }
  package_->assign(value);
}
inline void FileDescriptorProto::set_package(const char* value, size_t size) {
  set_has_package();
  if (package_ == &::google::protobuf::internal::kEmptyString) {
    package_ = new ::std::string;
  }
  package_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileDescriptorProto::mutable_package() {
  set_has_package();
  if (package_ == &::google::protobuf::internal::kEmptyString) {
    package_ = new ::std::string;
  }
  return package_;
}
inline ::std::string* FileDescriptorProto::release_package() {
  clear_has_package();
  if (package_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = package_;
    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return dependency_.Get(index);
}
inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
  return dependency_.Mutable(index);
}
inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
  dependency_.Mutable(index)->assign(value);
}
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
  dependency_.Mutable(index)->assign(value);
}
inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
  dependency_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileDescriptorProto::add_dependency() {
  return dependency_.Add();
}
inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
  dependency_.Add()->assign(value);
}
inline void FileDescriptorProto::add_dependency(const char* value) {
  dependency_.Add()->assign(value);
}
inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
  dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
FileDescriptorProto::dependency() const {
  return dependency_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
FileDescriptorProto::mutable_dependency() {
  return &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 {
  return message_type_.Get(index);
}
inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
  return message_type_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
  return message_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
FileDescriptorProto::message_type() const {
  return message_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
FileDescriptorProto::mutable_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 {
  return enum_type_.Get(index);
}
inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
  return enum_type_.Mutable(index);
}
inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
  return enum_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
FileDescriptorProto::enum_type() const {
  return enum_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
FileDescriptorProto::mutable_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 {
  return service_.Get(index);
}
inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
  return service_.Mutable(index);
}
inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
  return service_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
FileDescriptorProto::service() const {
  return service_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
FileDescriptorProto::mutable_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 {
  return extension_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
  return extension_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
  return extension_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
FileDescriptorProto::extension() const {
  return extension_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
FileDescriptorProto::mutable_extension() {
  return &extension_;
}

// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void FileDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000080u;
}
inline void FileDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void FileDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
  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;
  return options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::FileOptions* temp = options_;
  options_ = NULL;
  return temp;
}

// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
inline bool FileDescriptorProto::has_source_code_info() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void FileDescriptorProto::set_has_source_code_info() {
  _has_bits_[0] |= 0x00000100u;
}
inline void FileDescriptorProto::clear_has_source_code_info() {
  _has_bits_[0] &= ~0x00000100u;
}
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 {
  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;
  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;
}

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

// 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 {
  return start_;
}
inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
  set_has_start();
  start_ = value;
}

// 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 {
  return end_;
}
inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
  set_has_end();
  end_ = value;
}

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

// 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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& DescriptorProto::name() const {
  return *name_;
}
inline void DescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void DescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void DescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* DescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* DescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return field_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
  return field_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
  return field_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
DescriptorProto::field() const {
  return field_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_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 {
  return extension_.Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
  return extension_.Mutable(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
  return extension_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
DescriptorProto::extension() const {
  return extension_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_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 {
  return nested_type_.Get(index);
}
inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
  return nested_type_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
  return nested_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
DescriptorProto::nested_type() const {
  return nested_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
DescriptorProto::mutable_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 {
  return enum_type_.Get(index);
}
inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
  return enum_type_.Mutable(index);
}
inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
  return enum_type_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
DescriptorProto::enum_type() const {
  return enum_type_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
DescriptorProto::mutable_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 {
  return extension_range_.Get(index);
}
inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
  return extension_range_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
  return extension_range_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
DescriptorProto::extension_range() const {
  return extension_range_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
DescriptorProto::mutable_extension_range() {
  return &extension_range_;
}

// optional .google.protobuf.MessageOptions options = 7;
inline bool DescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void DescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000040u;
}
inline void DescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void DescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
  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;
  return options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::MessageOptions* temp = options_;
  options_ = NULL;
  return temp;
}

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

// 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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& FieldDescriptorProto::name() const {
  return *name_;
}
inline void FieldDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void FieldDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* FieldDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return number_;
}
inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
  set_has_number();
  number_ = value;
}

// 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 {
  return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
}
inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
  GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
  set_has_label();
  label_ = value;
}

// 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 {
  return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
}
inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
  GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
  set_has_type();
  type_ = value;
}

// 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::kEmptyString) {
    type_name_->clear();
  }
  clear_has_type_name();
}
inline const ::std::string& FieldDescriptorProto::type_name() const {
  return *type_name_;
}
inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::kEmptyString) {
    type_name_ = new ::std::string;
  }
  type_name_->assign(value);
}
inline void FieldDescriptorProto::set_type_name(const char* value) {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::kEmptyString) {
    type_name_ = new ::std::string;
  }
  type_name_->assign(value);
}
inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::kEmptyString) {
    type_name_ = new ::std::string;
  }
  type_name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_type_name() {
  set_has_type_name();
  if (type_name_ == &::google::protobuf::internal::kEmptyString) {
    type_name_ = new ::std::string;
  }
  return type_name_;
}
inline ::std::string* FieldDescriptorProto::release_type_name() {
  clear_has_type_name();
  if (type_name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = type_name_;
    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    extendee_->clear();
  }
  clear_has_extendee();
}
inline const ::std::string& FieldDescriptorProto::extendee() const {
  return *extendee_;
}
inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::kEmptyString) {
    extendee_ = new ::std::string;
  }
  extendee_->assign(value);
}
inline void FieldDescriptorProto::set_extendee(const char* value) {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::kEmptyString) {
    extendee_ = new ::std::string;
  }
  extendee_->assign(value);
}
inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::kEmptyString) {
    extendee_ = new ::std::string;
  }
  extendee_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_extendee() {
  set_has_extendee();
  if (extendee_ == &::google::protobuf::internal::kEmptyString) {
    extendee_ = new ::std::string;
  }
  return extendee_;
}
inline ::std::string* FieldDescriptorProto::release_extendee() {
  clear_has_extendee();
  if (extendee_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = extendee_;
    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    default_value_->clear();
  }
  clear_has_default_value();
}
inline const ::std::string& FieldDescriptorProto::default_value() const {
  return *default_value_;
}
inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::kEmptyString) {
    default_value_ = new ::std::string;
  }
  default_value_->assign(value);
}
inline void FieldDescriptorProto::set_default_value(const char* value) {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::kEmptyString) {
    default_value_ = new ::std::string;
  }
  default_value_->assign(value);
}
inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::kEmptyString) {
    default_value_ = new ::std::string;
  }
  default_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_default_value() {
  set_has_default_value();
  if (default_value_ == &::google::protobuf::internal::kEmptyString) {
    default_value_ = new ::std::string;
  }
  return default_value_;
}
inline ::std::string* FieldDescriptorProto::release_default_value() {
  clear_has_default_value();
  if (default_value_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = default_value_;
    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// optional .google.protobuf.FieldOptions options = 8;
inline bool FieldDescriptorProto::has_options() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void FieldDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000080u;
}
inline void FieldDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void FieldDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
  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;
  return options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::FieldOptions* temp = options_;
  options_ = NULL;
  return temp;
}

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

// 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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& EnumDescriptorProto::name() const {
  return *name_;
}
inline void EnumDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void EnumDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* EnumDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* EnumDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return value_.Get(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
  return value_.Mutable(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
  return value_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
EnumDescriptorProto::value() const {
  return value_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
EnumDescriptorProto::mutable_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 {
  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;
  return options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::EnumOptions* temp = options_;
  options_ = NULL;
  return temp;
}

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

// 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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& EnumValueDescriptorProto::name() const {
  return *name_;
}
inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void EnumValueDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* EnumValueDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* EnumValueDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return number_;
}
inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
  set_has_number();
  number_ = value;
}

// 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 {
  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;
  return options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::EnumValueOptions* temp = options_;
  options_ = NULL;
  return temp;
}

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

// 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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& ServiceDescriptorProto::name() const {
  return *name_;
}
inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void ServiceDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* ServiceDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* ServiceDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return method_.Get(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
  return method_.Mutable(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
  return method_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
ServiceDescriptorProto::method() const {
  return method_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
ServiceDescriptorProto::mutable_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 {
  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;
  return options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::ServiceOptions* temp = options_;
  options_ = NULL;
  return temp;
}

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

// 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::kEmptyString) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& MethodDescriptorProto::name() const {
  return *name_;
}
inline void MethodDescriptorProto::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void MethodDescriptorProto::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(value);
}
inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* MethodDescriptorProto::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    name_ = new ::std::string;
  }
  return name_;
}
inline ::std::string* MethodDescriptorProto::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    input_type_->clear();
  }
  clear_has_input_type();
}
inline const ::std::string& MethodDescriptorProto::input_type() const {
  return *input_type_;
}
inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::kEmptyString) {
    input_type_ = new ::std::string;
  }
  input_type_->assign(value);
}
inline void MethodDescriptorProto::set_input_type(const char* value) {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::kEmptyString) {
    input_type_ = new ::std::string;
  }
  input_type_->assign(value);
}
inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::kEmptyString) {
    input_type_ = new ::std::string;
  }
  input_type_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* MethodDescriptorProto::mutable_input_type() {
  set_has_input_type();
  if (input_type_ == &::google::protobuf::internal::kEmptyString) {
    input_type_ = new ::std::string;
  }
  return input_type_;
}
inline ::std::string* MethodDescriptorProto::release_input_type() {
  clear_has_input_type();
  if (input_type_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = input_type_;
    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    output_type_->clear();
  }
  clear_has_output_type();
}
inline const ::std::string& MethodDescriptorProto::output_type() const {
  return *output_type_;
}
inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::kEmptyString) {
    output_type_ = new ::std::string;
  }
  output_type_->assign(value);
}
inline void MethodDescriptorProto::set_output_type(const char* value) {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::kEmptyString) {
    output_type_ = new ::std::string;
  }
  output_type_->assign(value);
}
inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::kEmptyString) {
    output_type_ = new ::std::string;
  }
  output_type_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* MethodDescriptorProto::mutable_output_type() {
  set_has_output_type();
  if (output_type_ == &::google::protobuf::internal::kEmptyString) {
    output_type_ = new ::std::string;
  }
  return output_type_;
}
inline ::std::string* MethodDescriptorProto::release_output_type() {
  clear_has_output_type();
  if (output_type_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = output_type_;
    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  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;
  return options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
  clear_has_options();
  ::google::protobuf::MethodOptions* temp = options_;
  options_ = NULL;
  return temp;
}

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

// 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::kEmptyString) {
    java_package_->clear();
  }
  clear_has_java_package();
}
inline const ::std::string& FileOptions::java_package() const {
  return *java_package_;
}
inline void FileOptions::set_java_package(const ::std::string& value) {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::kEmptyString) {
    java_package_ = new ::std::string;
  }
  java_package_->assign(value);
}
inline void FileOptions::set_java_package(const char* value) {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::kEmptyString) {
    java_package_ = new ::std::string;
  }
  java_package_->assign(value);
}
inline void FileOptions::set_java_package(const char* value, size_t size) {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::kEmptyString) {
    java_package_ = new ::std::string;
  }
  java_package_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileOptions::mutable_java_package() {
  set_has_java_package();
  if (java_package_ == &::google::protobuf::internal::kEmptyString) {
    java_package_ = new ::std::string;
  }
  return java_package_;
}
inline ::std::string* FileOptions::release_java_package() {
  clear_has_java_package();
  if (java_package_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = java_package_;
    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    java_outer_classname_->clear();
  }
  clear_has_java_outer_classname();
}
inline const ::std::string& FileOptions::java_outer_classname() const {
  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::kEmptyString) {
    java_outer_classname_ = new ::std::string;
  }
  java_outer_classname_->assign(value);
}
inline void FileOptions::set_java_outer_classname(const char* value) {
  set_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
    java_outer_classname_ = new ::std::string;
  }
  java_outer_classname_->assign(value);
}
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::kEmptyString) {
    java_outer_classname_ = new ::std::string;
  }
  java_outer_classname_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileOptions::mutable_java_outer_classname() {
  set_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
    java_outer_classname_ = new ::std::string;
  }
  return java_outer_classname_;
}
inline ::std::string* FileOptions::release_java_outer_classname() {
  clear_has_java_outer_classname();
  if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = java_outer_classname_;
    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return java_multiple_files_;
}
inline void FileOptions::set_java_multiple_files(bool value) {
  set_has_java_multiple_files();
  java_multiple_files_ = value;
}

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

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

// optional bool cc_generic_services = 16 [default = false];
inline bool FileOptions::has_cc_generic_services() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void FileOptions::set_has_cc_generic_services() {
  _has_bits_[0] |= 0x00000020u;
}
inline void FileOptions::clear_has_cc_generic_services() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void FileOptions::clear_cc_generic_services() {
  cc_generic_services_ = false;
  clear_has_cc_generic_services();
}
inline bool FileOptions::cc_generic_services() const {
  return cc_generic_services_;
}
inline void FileOptions::set_cc_generic_services(bool value) {
  set_has_cc_generic_services();
  cc_generic_services_ = value;
}

// optional bool java_generic_services = 17 [default = false];
inline bool FileOptions::has_java_generic_services() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void FileOptions::set_has_java_generic_services() {
  _has_bits_[0] |= 0x00000040u;
}
inline void FileOptions::clear_has_java_generic_services() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void FileOptions::clear_java_generic_services() {
  java_generic_services_ = false;
  clear_has_java_generic_services();
}
inline bool FileOptions::java_generic_services() const {
  return java_generic_services_;
}
inline void FileOptions::set_java_generic_services(bool value) {
  set_has_java_generic_services();
  java_generic_services_ = value;
}

// optional bool py_generic_services = 18 [default = false];
inline bool FileOptions::has_py_generic_services() const {
  return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void FileOptions::set_has_py_generic_services() {
  _has_bits_[0] |= 0x00000080u;
}
inline void FileOptions::clear_has_py_generic_services() {
  _has_bits_[0] &= ~0x00000080u;
}
inline void FileOptions::clear_py_generic_services() {
  py_generic_services_ = false;
  clear_has_py_generic_services();
}
inline bool FileOptions::py_generic_services() const {
  return py_generic_services_;
}
inline void FileOptions::set_py_generic_services(bool value) {
  set_has_py_generic_services();
  py_generic_services_ = value;
}

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
FileOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FileOptions::mutable_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 {
  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;
}

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

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
MessageOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MessageOptions::mutable_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 {
  return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
}
inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
  GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value));
  set_has_ctype();
  ctype_ = value;
}

// 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 {
  return packed_;
}
inline void FieldOptions::set_packed(bool value) {
  set_has_packed();
  packed_ = value;
}

// optional bool deprecated = 3 [default = false];
inline bool FieldOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FieldOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FieldOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FieldOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool FieldOptions::deprecated() const {
  return deprecated_;
}
inline void FieldOptions::set_deprecated(bool value) {
  set_has_deprecated();
  deprecated_ = value;
}

// optional string experimental_map_key = 9;
inline bool FieldOptions::has_experimental_map_key() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FieldOptions::set_has_experimental_map_key() {
  _has_bits_[0] |= 0x00000008u;
}
inline void FieldOptions::clear_has_experimental_map_key() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void FieldOptions::clear_experimental_map_key() {
  if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
    experimental_map_key_->clear();
  }
  clear_has_experimental_map_key();
}
inline const ::std::string& FieldOptions::experimental_map_key() const {
  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::kEmptyString) {
    experimental_map_key_ = new ::std::string;
  }
  experimental_map_key_->assign(value);
}
inline void FieldOptions::set_experimental_map_key(const char* value) {
  set_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
    experimental_map_key_ = new ::std::string;
  }
  experimental_map_key_->assign(value);
}
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::kEmptyString) {
    experimental_map_key_ = new ::std::string;
  }
  experimental_map_key_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldOptions::mutable_experimental_map_key() {
  set_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
    experimental_map_key_ = new ::std::string;
  }
  return experimental_map_key_;
}
inline ::std::string* FieldOptions::release_experimental_map_key() {
  clear_has_experimental_map_key();
  if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = experimental_map_key_;
    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
FieldOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FieldOptions::mutable_uninterpreted_option() {
  return &uninterpreted_option_;
}

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

// EnumOptions

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
EnumOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumOptions::mutable_uninterpreted_option() {
  return &uninterpreted_option_;
}

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

// EnumValueOptions

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
EnumValueOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumValueOptions::mutable_uninterpreted_option() {
  return &uninterpreted_option_;
}

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

// ServiceOptions

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
ServiceOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
ServiceOptions::mutable_uninterpreted_option() {
  return &uninterpreted_option_;
}

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

// MethodOptions

// 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 {
  return uninterpreted_option_.Get(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
  return uninterpreted_option_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
  return uninterpreted_option_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
MethodOptions::uninterpreted_option() const {
  return uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MethodOptions::mutable_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::kEmptyString) {
    name_part_->clear();
  }
  clear_has_name_part();
}
inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
  return *name_part_;
}
inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::kEmptyString) {
    name_part_ = new ::std::string;
  }
  name_part_->assign(value);
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::kEmptyString) {
    name_part_ = new ::std::string;
  }
  name_part_->assign(value);
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::kEmptyString) {
    name_part_ = new ::std::string;
  }
  name_part_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
  set_has_name_part();
  if (name_part_ == &::google::protobuf::internal::kEmptyString) {
    name_part_ = new ::std::string;
  }
  return name_part_;
}
inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
  clear_has_name_part();
  if (name_part_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = name_part_;
    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return is_extension_;
}
inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
  set_has_is_extension();
  is_extension_ = value;
}

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

// 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 {
  return name_.Get(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
  return name_.Mutable(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
  return name_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
UninterpretedOption::name() const {
  return name_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
UninterpretedOption::mutable_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::kEmptyString) {
    identifier_value_->clear();
  }
  clear_has_identifier_value();
}
inline const ::std::string& UninterpretedOption::identifier_value() const {
  return *identifier_value_;
}
inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
    identifier_value_ = new ::std::string;
  }
  identifier_value_->assign(value);
}
inline void UninterpretedOption::set_identifier_value(const char* value) {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
    identifier_value_ = new ::std::string;
  }
  identifier_value_->assign(value);
}
inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
    identifier_value_ = new ::std::string;
  }
  identifier_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption::mutable_identifier_value() {
  set_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
    identifier_value_ = new ::std::string;
  }
  return identifier_value_;
}
inline ::std::string* UninterpretedOption::release_identifier_value() {
  clear_has_identifier_value();
  if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = identifier_value_;
    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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 {
  return positive_int_value_;
}
inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
  set_has_positive_int_value();
  positive_int_value_ = 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 {
  return negative_int_value_;
}
inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
  set_has_negative_int_value();
  negative_int_value_ = 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 {
  return double_value_;
}
inline void UninterpretedOption::set_double_value(double value) {
  set_has_double_value();
  double_value_ = 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::kEmptyString) {
    string_value_->clear();
  }
  clear_has_string_value();
}
inline const ::std::string& UninterpretedOption::string_value() const {
  return *string_value_;
}
inline void UninterpretedOption::set_string_value(const ::std::string& value) {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::kEmptyString) {
    string_value_ = new ::std::string;
  }
  string_value_->assign(value);
}
inline void UninterpretedOption::set_string_value(const char* value) {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::kEmptyString) {
    string_value_ = new ::std::string;
  }
  string_value_->assign(value);
}
inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::kEmptyString) {
    string_value_ = new ::std::string;
  }
  string_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption::mutable_string_value() {
  set_has_string_value();
  if (string_value_ == &::google::protobuf::internal::kEmptyString) {
    string_value_ = new ::std::string;
  }
  return string_value_;
}
inline ::std::string* UninterpretedOption::release_string_value() {
  clear_has_string_value();
  if (string_value_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = string_value_;
    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

// 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::kEmptyString) {
    aggregate_value_->clear();
  }
  clear_has_aggregate_value();
}
inline const ::std::string& UninterpretedOption::aggregate_value() const {
  return *aggregate_value_;
}
inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
    aggregate_value_ = new ::std::string;
  }
  aggregate_value_->assign(value);
}
inline void UninterpretedOption::set_aggregate_value(const char* value) {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
    aggregate_value_ = new ::std::string;
  }
  aggregate_value_->assign(value);
}
inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
    aggregate_value_ = new ::std::string;
  }
  aggregate_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
  set_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
    aggregate_value_ = new ::std::string;
  }
  return aggregate_value_;
}
inline ::std::string* UninterpretedOption::release_aggregate_value() {
  clear_has_aggregate_value();
  if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
    return NULL;
  } else {
    ::std::string* temp = aggregate_value_;
    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
    return temp;
  }
}

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

// 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 {
  return path_.Get(index);
}
inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
  path_.Set(index, value);
}
inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
  path_.Add(value);
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
SourceCodeInfo_Location::path() const {
  return path_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
SourceCodeInfo_Location::mutable_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 {
  return span_.Get(index);
}
inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
  span_.Set(index, value);
}
inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
  span_.Add(value);
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
SourceCodeInfo_Location::span() const {
  return span_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
SourceCodeInfo_Location::mutable_span() {
  return &span_;
}

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

// 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 {
  return location_.Get(index);
}
inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
  return location_.Mutable(index);
}
inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
  return location_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
SourceCodeInfo::location() const {
  return location_;
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
SourceCodeInfo::mutable_location() {
  return &location_;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

#ifndef SWIG
namespace google {
namespace protobuf {

template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() {
  return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
}
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() {
  return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
}
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() {
  return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
}
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
