// 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 < 2005000
#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 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)

namespace google {
namespace protobuf {

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

class FileDescriptorSet;
class FileDescriptorProto;
class DescriptorProto;
class DescriptorProto_ExtensionRange;
class FieldDescriptorProto;
class 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();
  inline void set_allocated_name(::std::string* name);

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

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

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

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

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

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

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

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

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::std::string* name_;
  ::std::string* package_;
  ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
  ::google::protobuf::FileOptions* options_;
  ::google::protobuf::SourceCodeInfo* source_code_info_;

  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(11 + 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();
  inline void set_allocated_name(::std::string* name);

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

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

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

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

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::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();
  inline void set_allocated_name(::std::string* name);

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

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

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

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

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

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

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

  // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_number();
  inline void clear_has_number();
  inline void set_has_label();
  inline void clear_has_label();
  inline void set_has_type();
  inline void clear_has_type();
  inline void set_has_type_name();
  inline void clear_has_type_name();
  inline void set_has_extendee();
  inline void clear_has_extendee();
  inline void set_has_default_value();
  inline void clear_has_default_value();
  inline void set_has_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();
  inline void set_allocated_name(::std::string* name);

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::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();
  inline void set_allocated_name(::std::string* name);

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::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();
  inline void set_allocated_name(::std::string* name);

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::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();
  inline void set_allocated_name(::std::string* name);

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

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::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();
  inline void set_allocated_java_package(::std::string* java_package);

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

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

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

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

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

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

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

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

  // 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_go_package();
  inline void clear_has_go_package();
  inline void set_has_cc_generic_services();
  inline void clear_has_cc_generic_services();
  inline void set_has_java_generic_services();
  inline void clear_has_java_generic_services();
  inline void set_has_py_generic_services();
  inline void clear_has_py_generic_services();

  ::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_;
  ::std::string* go_package_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool py_generic_services_;

  mutable int _cached_size_;
  ::google::protobuf::uint32 _has_bits_[(10 + 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 lazy = 5 [default = false];
  inline bool has_lazy() const;
  inline void clear_lazy();
  static const int kLazyFieldNumber = 5;
  inline bool lazy() const;
  inline void set_lazy(bool value);

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

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

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

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  int ctype_;
  bool packed_;
  bool lazy_;
  bool deprecated_;
  bool weak_;
  ::std::string* experimental_map_key_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;

  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 FieldOptions* default_instance_;
};
// -------------------------------------------------------------------

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

  EnumOptions(const EnumOptions& from);

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

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

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

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

  void Swap(EnumOptions* other);

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

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:

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

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

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

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

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool allow_alias_;

  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 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();
  inline void set_allocated_name_part(::std::string* name_part);

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::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();
  inline void set_allocated_identifier_value(::std::string* identifier_value);

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

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

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

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::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();

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

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

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

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
  mutable int _path_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
  mutable int _span_cached_byte_size_;
  ::std::string* leading_comments_;
  ::std::string* trailing_comments_;

  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 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;
  }
}
inline void FileDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void FileDescriptorProto::set_allocated_package(::std::string* package) {
  if (package_ != &::google::protobuf::internal::kEmptyString) {
    delete package_;
  }
  if (package) {
    set_has_package();
    package_ = package;
  } else {
    clear_has_package();
    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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 int32 public_dependency = 10;
inline int FileDescriptorProto::public_dependency_size() const {
  return public_dependency_.size();
}
inline void FileDescriptorProto::clear_public_dependency() {
  public_dependency_.Clear();
}
inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const {
  return public_dependency_.Get(index);
}
inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) {
  public_dependency_.Set(index, value);
}
inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) {
  public_dependency_.Add(value);
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
FileDescriptorProto::public_dependency() const {
  return public_dependency_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
FileDescriptorProto::mutable_public_dependency() {
  return &public_dependency_;
}

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

// repeated .google.protobuf.DescriptorProto message_type = 4;
inline int FileDescriptorProto::message_type_size() const {
  return message_type_.size();
}
inline void FileDescriptorProto::clear_message_type() {
  message_type_.Clear();
}
inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
  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] & 0x00000200u) != 0;
}
inline void FileDescriptorProto::set_has_options() {
  _has_bits_[0] |= 0x00000200u;
}
inline void FileDescriptorProto::clear_has_options() {
  _has_bits_[0] &= ~0x00000200u;
}
inline void FileDescriptorProto::clear_options() {
  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
  clear_has_options();
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
  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;
}
inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
inline bool FileDescriptorProto::has_source_code_info() const {
  return (_has_bits_[0] & 0x00000400u) != 0;
}
inline void FileDescriptorProto::set_has_source_code_info() {
  _has_bits_[0] |= 0x00000400u;
}
inline void FileDescriptorProto::clear_has_source_code_info() {
  _has_bits_[0] &= ~0x00000400u;
}
inline void FileDescriptorProto::clear_source_code_info() {
  if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
  clear_has_source_code_info();
}
inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
  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;
}
inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
  delete source_code_info_;
  source_code_info_ = source_code_info;
  if (source_code_info) {
    set_has_source_code_info();
  } else {
    clear_has_source_code_info();
  }
}

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

// 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;
  }
}
inline void DescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
}
inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

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

// FieldDescriptorProto

// optional string name = 1;
inline bool FieldDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FieldDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FieldDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FieldDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::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;
  }
}
inline void FieldDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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) {
  assert(::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) {
  assert(::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;
  }
}
inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
  if (type_name_ != &::google::protobuf::internal::kEmptyString) {
    delete type_name_;
  }
  if (type_name) {
    set_has_type_name();
    type_name_ = type_name;
  } else {
    clear_has_type_name();
    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
  if (extendee_ != &::google::protobuf::internal::kEmptyString) {
    delete extendee_;
  }
  if (extendee) {
    set_has_extendee();
    extendee_ = extendee;
  } else {
    clear_has_extendee();
    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
  if (default_value_ != &::google::protobuf::internal::kEmptyString) {
    delete default_value_;
  }
  if (default_value) {
    set_has_default_value();
    default_value_ = default_value;
  } else {
    clear_has_default_value();
    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
}
inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

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

// 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;
  }
}
inline void EnumDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
}
inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

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

// EnumValueDescriptorProto

// optional string name = 1;
inline bool EnumValueDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void EnumValueDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void EnumValueDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void EnumValueDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::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;
  }
}
inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
}
inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

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

// ServiceDescriptorProto

// optional string name = 1;
inline bool ServiceDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void ServiceDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void ServiceDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void ServiceDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::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;
  }
}
inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
}
inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

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

// MethodDescriptorProto

// optional string name = 1;
inline bool MethodDescriptorProto::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MethodDescriptorProto::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MethodDescriptorProto::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MethodDescriptorProto::clear_name() {
  if (name_ != &::google::protobuf::internal::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;
  }
}
inline void MethodDescriptorProto::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
  if (input_type_ != &::google::protobuf::internal::kEmptyString) {
    delete input_type_;
  }
  if (input_type) {
    set_has_input_type();
    input_type_ = input_type;
  } else {
    clear_has_input_type();
    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
  if (output_type_ != &::google::protobuf::internal::kEmptyString) {
    delete output_type_;
  }
  if (output_type) {
    set_has_output_type();
    output_type_ = output_type;
  } else {
    clear_has_output_type();
    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
}
inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
  delete options_;
  options_ = options;
  if (options) {
    set_has_options();
  } else {
    clear_has_options();
  }
}

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

// FileOptions

// optional string java_package = 1;
inline bool FileOptions::has_java_package() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FileOptions::set_has_java_package() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FileOptions::clear_has_java_package() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FileOptions::clear_java_package() {
  if (java_package_ != &::google::protobuf::internal::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;
  }
}
inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
  if (java_package_ != &::google::protobuf::internal::kEmptyString) {
    delete java_package_;
  }
  if (java_package) {
    set_has_java_package();
    java_package_ = java_package;
  } else {
    clear_has_java_package();
    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
  if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
    delete java_outer_classname_;
  }
  if (java_outer_classname) {
    set_has_java_outer_classname();
    java_outer_classname_ = java_outer_classname;
  } else {
    clear_has_java_outer_classname();
    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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) {
  assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
  set_has_optimize_for();
  optimize_for_ = value;
}

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

// optional bool cc_generic_services = 16 [default = false];
inline bool FileOptions::has_cc_generic_services() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void FileOptions::set_has_cc_generic_services() {
  _has_bits_[0] |= 0x00000040u;
}
inline void FileOptions::clear_has_cc_generic_services() {
  _has_bits_[0] &= ~0x00000040u;
}
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] & 0x00000080u) != 0;
}
inline void FileOptions::set_has_java_generic_services() {
  _has_bits_[0] |= 0x00000080u;
}
inline void FileOptions::clear_has_java_generic_services() {
  _has_bits_[0] &= ~0x00000080u;
}
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] & 0x00000100u) != 0;
}
inline void FileOptions::set_has_py_generic_services() {
  _has_bits_[0] |= 0x00000100u;
}
inline void FileOptions::clear_has_py_generic_services() {
  _has_bits_[0] &= ~0x00000100u;
}
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) {
  assert(::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 lazy = 5 [default = false];
inline bool FieldOptions::has_lazy() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FieldOptions::set_has_lazy() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FieldOptions::clear_has_lazy() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FieldOptions::clear_lazy() {
  lazy_ = false;
  clear_has_lazy();
}
inline bool FieldOptions::lazy() const {
  return lazy_;
}
inline void FieldOptions::set_lazy(bool value) {
  set_has_lazy();
  lazy_ = value;
}

// optional bool deprecated = 3 [default = false];
inline bool FieldOptions::has_deprecated() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FieldOptions::set_has_deprecated() {
  _has_bits_[0] |= 0x00000008u;
}
inline void FieldOptions::clear_has_deprecated() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void FieldOptions::clear_deprecated() {
  deprecated_ = false;
  clear_has_deprecated();
}
inline bool FieldOptions::deprecated() const {
  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] & 0x00000010u) != 0;
}
inline void FieldOptions::set_has_experimental_map_key() {
  _has_bits_[0] |= 0x00000010u;
}
inline void FieldOptions::clear_has_experimental_map_key() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void FieldOptions::clear_experimental_map_key() {
  if (experimental_map_key_ != &::google::protobuf::internal::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;
  }
}
inline void FieldOptions::set_allocated_experimental_map_key(::std::string* experimental_map_key) {
  if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
    delete experimental_map_key_;
  }
  if (experimental_map_key) {
    set_has_experimental_map_key();
    experimental_map_key_ = experimental_map_key;
  } else {
    clear_has_experimental_map_key();
    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

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

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

// optional bool allow_alias = 2 [default = true];
inline bool EnumOptions::has_allow_alias() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void EnumOptions::set_has_allow_alias() {
  _has_bits_[0] |= 0x00000001u;
}
inline void EnumOptions::clear_has_allow_alias() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void EnumOptions::clear_allow_alias() {
  allow_alias_ = true;
  clear_has_allow_alias();
}
inline bool EnumOptions::allow_alias() const {
  return allow_alias_;
}
inline void EnumOptions::set_allow_alias(bool value) {
  set_has_allow_alias();
  allow_alias_ = value;
}

// 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;
  }
}
inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
  if (name_part_ != &::google::protobuf::internal::kEmptyString) {
    delete name_part_;
  }
  if (name_part) {
    set_has_name_part();
    name_part_ = name_part;
  } else {
    clear_has_name_part();
    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
  if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
    delete identifier_value_;
  }
  if (identifier_value) {
    set_has_identifier_value();
    identifier_value_ = identifier_value;
  } else {
    clear_has_identifier_value();
    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
  if (string_value_ != &::google::protobuf::internal::kEmptyString) {
    delete string_value_;
  }
  if (string_value) {
    set_has_string_value();
    string_value_ = string_value;
  } else {
    clear_has_string_value();
    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

// 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;
  }
}
inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
  if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
    delete aggregate_value_;
  }
  if (aggregate_value) {
    set_has_aggregate_value();
    aggregate_value_ = aggregate_value;
  } else {
    clear_has_aggregate_value();
    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  }
}

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

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

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

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

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

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