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

#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
// @@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 DescriptorProto;
class DescriptorProto_ExtensionRange;
class DescriptorProto_ReservedRange;
class EnumDescriptorProto;
class EnumOptions;
class EnumValueDescriptorProto;
class EnumValueOptions;
class FieldDescriptorProto;
class FieldOptions;
class FileDescriptorProto;
class FileDescriptorSet;
class FileOptions;
class GeneratedCodeInfo;
class GeneratedCodeInfo_Annotation;
class MessageOptions;
class MethodDescriptorProto;
class MethodOptions;
class OneofDescriptorProto;
class ServiceDescriptorProto;
class ServiceOptions;
class SourceCodeInfo;
class SourceCodeInfo_Location;
class UninterpretedOption;
class UninterpretedOption_NamePart;

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);
}
enum FieldOptions_JSType {
  FieldOptions_JSType_JS_NORMAL = 0,
  FieldOptions_JSType_JS_STRING = 1,
  FieldOptions_JSType_JS_NUMBER = 2
};
LIBPROTOBUF_EXPORT bool FieldOptions_JSType_IsValid(int value);
const FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL;
const FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER;
const int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1;

LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor();
inline const ::std::string& FieldOptions_JSType_Name(FieldOptions_JSType value) {
  return ::google::protobuf::internal::NameOfEnum(
    FieldOptions_JSType_descriptor(), value);
}
inline bool FieldOptions_JSType_Parse(
    const ::std::string& name, FieldOptions_JSType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FieldOptions_JSType>(
    FieldOptions_JSType_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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(FileDescriptorSet* other);

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

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

  FileDescriptorSet* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(FileDescriptorSet* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

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

  FileDescriptorProto(const FileDescriptorProto& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(FileDescriptorProto* other);

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

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

  FileDescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(FileDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  // optional string syntax = 12;
  bool has_syntax() const;
  void clear_syntax();
  static const int kSyntaxFieldNumber = 12;
  const ::std::string& syntax() const;
  void set_syntax(const ::std::string& value);
  void set_syntax(const char* value);
  void set_syntax(const char* value, size_t size);
  ::std::string* mutable_syntax();
  ::std::string* release_syntax();
  void set_allocated_syntax(::std::string* syntax);

  // @@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();
  inline void set_has_syntax();
  inline void clear_has_syntax();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::internal::ArenaStringPtr 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_;
  ::google::protobuf::internal::ArenaStringPtr syntax_;
  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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(DescriptorProto_ExtensionRange* other);

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

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

  DescriptorProto_ExtensionRange* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(DescriptorProto_ExtensionRange* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

  // optional int32 end = 2;
  bool has_end() const;
  void clear_end();
  static const int kEndFieldNumber = 2;
  ::google::protobuf::int32 end() const;
  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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::int32 start_;
  ::google::protobuf::int32 end_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(DescriptorProto_ReservedRange* other);

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

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

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(DescriptorProto_ReservedRange* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

  void InitAsDefaultInstance();
  static DescriptorProto_ReservedRange* 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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(DescriptorProto* other);

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

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

  DescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(DescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef DescriptorProto_ExtensionRange ExtensionRange;
  typedef DescriptorProto_ReservedRange ReservedRange;

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

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

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

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

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

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

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

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

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

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  int reserved_range_size() const;
  void clear_reserved_range();
  static const int kReservedRangeFieldNumber = 9;
  const ::google::protobuf::DescriptorProto_ReservedRange& reserved_range(int index) const;
  ::google::protobuf::DescriptorProto_ReservedRange* mutable_reserved_range(int index);
  ::google::protobuf::DescriptorProto_ReservedRange* add_reserved_range();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >*
      mutable_reserved_range();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
      reserved_range() const;

  // repeated string reserved_name = 10;
  int reserved_name_size() const;
  void clear_reserved_name();
  static const int kReservedNameFieldNumber = 10;
  const ::std::string& reserved_name(int index) const;
  ::std::string* mutable_reserved_name(int index);
  void set_reserved_name(int index, const ::std::string& value);
  void set_reserved_name(int index, const char* value);
  void set_reserved_name(int index, const char* value, size_t size);
  ::std::string* add_reserved_name();
  void add_reserved_name(const ::std::string& value);
  void add_reserved_name(const char* value);
  void add_reserved_name(const char* value, size_t size);
  const ::google::protobuf::RepeatedPtrField< ::std::string>& reserved_name() const;
  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_reserved_name();

  // @@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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
  ::google::protobuf::MessageOptions* options_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_;
  ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

  void InitAsDefaultInstance();
  static 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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(FieldDescriptorProto* other);

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

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

  FieldDescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(FieldDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef 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;
  bool has_name() const;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

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

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

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

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

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

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

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

  // optional string json_name = 10;
  bool has_json_name() const;
  void clear_json_name();
  static const int kJsonNameFieldNumber = 10;
  const ::std::string& json_name() const;
  void set_json_name(const ::std::string& value);
  void set_json_name(const char* value);
  void set_json_name(const char* value, size_t size);
  ::std::string* mutable_json_name();
  ::std::string* release_json_name();
  void set_allocated_json_name(::std::string* json_name);

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

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

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

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

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

  OneofDescriptorProto(const OneofDescriptorProto& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(OneofDescriptorProto* other);

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

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

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(OneofDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  EnumDescriptorProto(const EnumDescriptorProto& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(EnumDescriptorProto* other);

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

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

  EnumDescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(EnumDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

  // optional .google.protobuf.EnumOptions options = 3;
  bool has_options() const;
  void clear_options();
  static const int kOptionsFieldNumber = 3;
  const ::google::protobuf::EnumOptions& options() const;
  ::google::protobuf::EnumOptions* mutable_options();
  ::google::protobuf::EnumOptions* release_options();
  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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
  ::google::protobuf::EnumOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  EnumValueDescriptorProto(const EnumValueDescriptorProto& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(EnumValueDescriptorProto* other);

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

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

  EnumValueDescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(EnumValueDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

  // optional .google.protobuf.EnumValueOptions options = 3;
  bool has_options() const;
  void clear_options();
  static const int kOptionsFieldNumber = 3;
  const ::google::protobuf::EnumValueOptions& options() const;
  ::google::protobuf::EnumValueOptions* mutable_options();
  ::google::protobuf::EnumValueOptions* release_options();
  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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::EnumValueOptions* options_;
  ::google::protobuf::int32 number_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  ServiceDescriptorProto(const ServiceDescriptorProto& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(ServiceDescriptorProto* other);

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

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

  ServiceDescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(ServiceDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

  // optional .google.protobuf.ServiceOptions options = 3;
  bool has_options() const;
  void clear_options();
  static const int kOptionsFieldNumber = 3;
  const ::google::protobuf::ServiceOptions& options() const;
  ::google::protobuf::ServiceOptions* mutable_options();
  ::google::protobuf::ServiceOptions* release_options();
  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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
  ::google::protobuf::ServiceOptions* options_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  MethodDescriptorProto(const MethodDescriptorProto& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(MethodDescriptorProto* other);

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

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

  MethodDescriptorProto* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(MethodDescriptorProto* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

  // optional bool client_streaming = 5 [default = false];
  bool has_client_streaming() const;
  void clear_client_streaming();
  static const int kClientStreamingFieldNumber = 5;
  bool client_streaming() const;
  void set_client_streaming(bool value);

  // optional bool server_streaming = 6 [default = false];
  bool has_server_streaming() const;
  void clear_server_streaming();
  static const int kServerStreamingFieldNumber = 6;
  bool server_streaming() const;
  void set_server_streaming(bool value);

  // @@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();
  inline void set_has_client_streaming();
  inline void clear_has_client_streaming();
  inline void set_has_server_streaming();
  inline void clear_has_server_streaming();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::internal::ArenaStringPtr input_type_;
  ::google::protobuf::internal::ArenaStringPtr output_type_;
  ::google::protobuf::MethodOptions* options_;
  bool client_streaming_;
  bool server_streaming_;
  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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(FileOptions* other);

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

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

  FileOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(FileOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef 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;
  bool has_java_package() const;
  void clear_java_package();
  static const int kJavaPackageFieldNumber = 1;
  const ::std::string& java_package() const;
  void set_java_package(const ::std::string& value);
  void set_java_package(const char* value);
  void set_java_package(const char* value, size_t size);
  ::std::string* mutable_java_package();
  ::std::string* release_java_package();
  void set_allocated_java_package(::std::string* java_package);

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

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

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

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

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

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

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

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

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

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

  // optional bool cc_enable_arenas = 31 [default = false];
  bool has_cc_enable_arenas() const;
  void clear_cc_enable_arenas();
  static const int kCcEnableArenasFieldNumber = 31;
  bool cc_enable_arenas() const;
  void set_cc_enable_arenas(bool value);

  // optional string objc_class_prefix = 36;
  bool has_objc_class_prefix() const;
  void clear_objc_class_prefix();
  static const int kObjcClassPrefixFieldNumber = 36;
  const ::std::string& objc_class_prefix() const;
  void set_objc_class_prefix(const ::std::string& value);
  void set_objc_class_prefix(const char* value);
  void set_objc_class_prefix(const char* value, size_t size);
  ::std::string* mutable_objc_class_prefix();
  ::std::string* release_objc_class_prefix();
  void set_allocated_objc_class_prefix(::std::string* objc_class_prefix);

  // optional string csharp_namespace = 37;
  bool has_csharp_namespace() const;
  void clear_csharp_namespace();
  static const int kCsharpNamespaceFieldNumber = 37;
  const ::std::string& csharp_namespace() const;
  void set_csharp_namespace(const ::std::string& value);
  void set_csharp_namespace(const char* value);
  void set_csharp_namespace(const char* value, size_t size);
  ::std::string* mutable_csharp_namespace();
  ::std::string* release_csharp_namespace();
  void set_allocated_csharp_namespace(::std::string* csharp_namespace);

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr java_package_;
  ::google::protobuf::internal::ArenaStringPtr java_outer_classname_;
  bool java_multiple_files_;
  bool java_generate_equals_and_hash_;
  bool java_string_check_utf8_;
  bool cc_generic_services_;
  int optimize_for_;
  ::google::protobuf::internal::ArenaStringPtr go_package_;
  ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
  ::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool java_generic_services_;
  bool py_generic_services_;
  bool deprecated_;
  bool cc_enable_arenas_;
  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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(MessageOptions* other);

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

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

  MessageOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(MessageOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

  // optional bool map_entry = 7;
  bool has_map_entry() const;
  void clear_map_entry();
  static const int kMapEntryFieldNumber = 7;
  bool map_entry() const;
  void set_map_entry(bool value);

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool message_set_wire_format_;
  bool no_standard_descriptor_accessor_;
  bool deprecated_;
  bool map_entry_;
  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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(FieldOptions* other);

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

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

  FieldOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(FieldOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef 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);
  }

  typedef FieldOptions_JSType JSType;
  static const JSType JS_NORMAL =
    FieldOptions_JSType_JS_NORMAL;
  static const JSType JS_STRING =
    FieldOptions_JSType_JS_STRING;
  static const JSType JS_NUMBER =
    FieldOptions_JSType_JS_NUMBER;
  static inline bool JSType_IsValid(int value) {
    return FieldOptions_JSType_IsValid(value);
  }
  static const JSType JSType_MIN =
    FieldOptions_JSType_JSType_MIN;
  static const JSType JSType_MAX =
    FieldOptions_JSType_JSType_MAX;
  static const int JSType_ARRAYSIZE =
    FieldOptions_JSType_JSType_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  JSType_descriptor() {
    return FieldOptions_JSType_descriptor();
  }
  static inline const ::std::string& JSType_Name(JSType value) {
    return FieldOptions_JSType_Name(value);
  }
  static inline bool JSType_Parse(const ::std::string& name,
      JSType* value) {
    return FieldOptions_JSType_Parse(name, value);
  }

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

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

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

  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
  bool has_jstype() const;
  void clear_jstype();
  static const int kJstypeFieldNumber = 6;
  ::google::protobuf::FieldOptions_JSType jstype() const;
  void set_jstype(::google::protobuf::FieldOptions_JSType value);

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

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

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

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

  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_jstype();
  inline void clear_has_jstype();
  inline void set_has_lazy();
  inline void clear_has_lazy();
  inline void set_has_deprecated();
  inline void clear_has_deprecated();
  inline void set_has_weak();
  inline void clear_has_weak();

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  int ctype_;
  int jstype_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
  bool packed_;
  bool lazy_;
  bool deprecated_;
  bool weak_;
  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 _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(EnumOptions* other);

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

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

  EnumOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(EnumOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

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

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

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

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

  EnumValueOptions(const EnumValueOptions& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(EnumValueOptions* other);

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

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

  EnumValueOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(EnumValueOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

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

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

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

  ServiceOptions(const ServiceOptions& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(ServiceOptions* other);

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

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

  ServiceOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(ServiceOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

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

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

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

  MethodOptions(const MethodOptions& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(MethodOptions* other);

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

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

  MethodOptions* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(MethodOptions* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

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

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

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

  UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(UninterpretedOption_NamePart* other);

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

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

  UninterpretedOption_NamePart* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(UninterpretedOption_NamePart* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

  // required bool is_extension = 2;
  bool has_is_extension() const;
  void clear_is_extension();
  static const int kIsExtensionFieldNumber = 2;
  bool is_extension() const;
  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();

  // helper for ByteSize()
  int RequiredFieldsByteSizeFallback() const;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_part_;
  bool is_extension_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  UninterpretedOption(const UninterpretedOption& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(UninterpretedOption* other);

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

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

  UninterpretedOption* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(UninterpretedOption* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef UninterpretedOption_NamePart NamePart;

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

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

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

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

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

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

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

  // optional string aggregate_value = 8;
  bool has_aggregate_value() const;
  void clear_aggregate_value();
  static const int kAggregateValueFieldNumber = 8;
  const ::std::string& aggregate_value() const;
  void set_aggregate_value(const ::std::string& value);
  void set_aggregate_value(const char* value);
  void set_aggregate_value(const char* value, size_t size);
  ::std::string* mutable_aggregate_value();
  ::std::string* release_aggregate_value();
  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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
  ::google::protobuf::internal::ArenaStringPtr identifier_value_;
  ::google::protobuf::uint64 positive_int_value_;
  ::google::protobuf::int64 negative_int_value_;
  double double_value_;
  ::google::protobuf::internal::ArenaStringPtr string_value_;
  ::google::protobuf::internal::ArenaStringPtr aggregate_value_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  SourceCodeInfo_Location(const SourceCodeInfo_Location& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(SourceCodeInfo_Location* other);

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

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

  SourceCodeInfo_Location* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(SourceCodeInfo_Location* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

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

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

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

  // repeated string leading_detached_comments = 6;
  int leading_detached_comments_size() const;
  void clear_leading_detached_comments();
  static const int kLeadingDetachedCommentsFieldNumber = 6;
  const ::std::string& leading_detached_comments(int index) const;
  ::std::string* mutable_leading_detached_comments(int index);
  void set_leading_detached_comments(int index, const ::std::string& value);
  void set_leading_detached_comments(int index, const char* value);
  void set_leading_detached_comments(int index, const char* value, size_t size);
  ::std::string* add_leading_detached_comments();
  void add_leading_detached_comments(const ::std::string& value);
  void add_leading_detached_comments(const char* value);
  void add_leading_detached_comments(const char* value, size_t size);
  const ::google::protobuf::RepeatedPtrField< ::std::string>& leading_detached_comments() const;
  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_leading_detached_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::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
  mutable int _path_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
  mutable int _span_cached_byte_size_;
  ::google::protobuf::internal::ArenaStringPtr leading_comments_;
  ::google::protobuf::internal::ArenaStringPtr trailing_comments_;
  ::google::protobuf::RepeatedPtrField< ::std::string> leading_detached_comments_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  SourceCodeInfo(const SourceCodeInfo& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(SourceCodeInfo* other);

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

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

  SourceCodeInfo* New(::google::protobuf::Arena* arena) 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;
  void InternalSwap(SourceCodeInfo* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef SourceCodeInfo_Location Location;

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

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

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

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

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

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

  GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(GeneratedCodeInfo_Annotation* other);

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

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

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(GeneratedCodeInfo_Annotation* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

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

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

  // optional string source_file = 2;
  bool has_source_file() const;
  void clear_source_file();
  static const int kSourceFileFieldNumber = 2;
  const ::std::string& source_file() const;
  void set_source_file(const ::std::string& value);
  void set_source_file(const char* value);
  void set_source_file(const char* value, size_t size);
  ::std::string* mutable_source_file();
  ::std::string* release_source_file();
  void set_allocated_source_file(::std::string* source_file);

  // optional int32 begin = 3;
  bool has_begin() const;
  void clear_begin();
  static const int kBeginFieldNumber = 3;
  ::google::protobuf::int32 begin() const;
  void set_begin(::google::protobuf::int32 value);

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

  // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
 private:
  inline void set_has_source_file();
  inline void clear_has_source_file();
  inline void set_has_begin();
  inline void clear_has_begin();
  inline void set_has_end();
  inline void clear_has_end();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
  mutable int _path_cached_byte_size_;
  ::google::protobuf::internal::ArenaStringPtr source_file_;
  ::google::protobuf::int32 begin_;
  ::google::protobuf::int32 end_;
  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();

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

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

  GeneratedCodeInfo(const GeneratedCodeInfo& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

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

  void Swap(GeneratedCodeInfo* other);

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

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

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

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(GeneratedCodeInfo* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _internal_metadata_.arena();
  }
  inline void* MaybeArenaPtr() const {
    return _internal_metadata_.raw_arena_ptr();
  }
  public:

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

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

  typedef GeneratedCodeInfo_Annotation Annotation;

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

  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  int annotation_size() const;
  void clear_annotation();
  static const int kAnnotationFieldNumber = 1;
  const ::google::protobuf::GeneratedCodeInfo_Annotation& annotation(int index) const;
  ::google::protobuf::GeneratedCodeInfo_Annotation* mutable_annotation(int index);
  ::google::protobuf::GeneratedCodeInfo_Annotation* add_annotation();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >*
      mutable_annotation();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >&
      annotation() const;

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_;
  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 GeneratedCodeInfo* default_instance_;
};
// ===================================================================


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

#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// FileDescriptorSet

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

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

// FileDescriptorProto

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

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

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

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

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

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

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

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

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

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

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

// optional string syntax = 12;
inline bool FileDescriptorProto::has_syntax() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void FileDescriptorProto::set_has_syntax() {
  _has_bits_[0] |= 0x00000800u;
}
inline void FileDescriptorProto::clear_has_syntax() {
  _has_bits_[0] &= ~0x00000800u;
}
inline void FileDescriptorProto::clear_syntax() {
  syntax_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_syntax();
}
inline const ::std::string& FileDescriptorProto::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.syntax)
  return syntax_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileDescriptorProto::set_syntax(const ::std::string& value) {
  set_has_syntax();
  syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
}
inline void FileDescriptorProto::set_syntax(const char* value) {
  set_has_syntax();
  syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax)
}
inline void FileDescriptorProto::set_syntax(const char* value, size_t size) {
  set_has_syntax();
  syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.syntax)
}
inline ::std::string* FileDescriptorProto::mutable_syntax() {
  set_has_syntax();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax)
  return syntax_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileDescriptorProto::release_syntax() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
  clear_has_syntax();
  return syntax_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileDescriptorProto::set_allocated_syntax(::std::string* syntax) {
  if (syntax != NULL) {
    set_has_syntax();
  } else {
    clear_has_syntax();
  }
  syntax_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), syntax);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax)
}

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

// DescriptorProto_ExtensionRange

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

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

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

// DescriptorProto_ReservedRange

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

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

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

// DescriptorProto

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

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

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

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

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

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

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

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

// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
inline int DescriptorProto::reserved_range_size() const {
  return reserved_range_.size();
}
inline void DescriptorProto::clear_reserved_range() {
  reserved_range_.Clear();
}
inline const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range)
  return reserved_range_.Get(index);
}
inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range)
  return reserved_range_.Mutable(index);
}
inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() {
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range)
  return reserved_range_.Add();
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >*
DescriptorProto::mutable_reserved_range() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range)
  return &reserved_range_;
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
DescriptorProto::reserved_range() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
  return reserved_range_;
}

// repeated string reserved_name = 10;
inline int DescriptorProto::reserved_name_size() const {
  return reserved_name_.size();
}
inline void DescriptorProto::clear_reserved_name() {
  reserved_name_.Clear();
}
inline const ::std::string& DescriptorProto::reserved_name(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name)
  return reserved_name_.Get(index);
}
inline ::std::string* DescriptorProto::mutable_reserved_name(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name)
  return reserved_name_.Mutable(index);
}
inline void DescriptorProto::set_reserved_name(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
  reserved_name_.Mutable(index)->assign(value);
}
inline void DescriptorProto::set_reserved_name(int index, const char* value) {
  reserved_name_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::set_reserved_name(int index, const char* value, size_t size) {
  reserved_name_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name)
}
inline ::std::string* DescriptorProto::add_reserved_name() {
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name)
  return reserved_name_.Add();
}
inline void DescriptorProto::add_reserved_name(const ::std::string& value) {
  reserved_name_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::add_reserved_name(const char* value) {
  reserved_name_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::add_reserved_name(const char* value, size_t size) {
  reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.DescriptorProto.reserved_name)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
DescriptorProto::reserved_name() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name)
  return reserved_name_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
DescriptorProto::mutable_reserved_name() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name)
  return &reserved_name_;
}

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

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

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

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

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

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

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

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

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

// optional string json_name = 10;
inline bool FieldDescriptorProto::has_json_name() const {
  return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void FieldDescriptorProto::set_has_json_name() {
  _has_bits_[0] |= 0x00000100u;
}
inline void FieldDescriptorProto::clear_has_json_name() {
  _has_bits_[0] &= ~0x00000100u;
}
inline void FieldDescriptorProto::clear_json_name() {
  json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_json_name();
}
inline const ::std::string& FieldDescriptorProto::json_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.json_name)
  return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FieldDescriptorProto::set_json_name(const ::std::string& value) {
  set_has_json_name();
  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name)
}
inline void FieldDescriptorProto::set_json_name(const char* value) {
  set_has_json_name();
  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name)
}
inline void FieldDescriptorProto::set_json_name(const char* value, size_t size) {
  set_has_json_name();
  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.json_name)
}
inline ::std::string* FieldDescriptorProto::mutable_json_name() {
  set_has_json_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.json_name)
  return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldDescriptorProto::release_json_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name)
  clear_has_json_name();
  return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FieldDescriptorProto::set_allocated_json_name(::std::string* json_name) {
  if (json_name != NULL) {
    set_has_json_name();
  } else {
    clear_has_json_name();
  }
  json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.json_name)
}

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

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

// OneofDescriptorProto

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

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

// EnumDescriptorProto

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

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

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

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

// EnumValueDescriptorProto

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

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

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

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

// ServiceDescriptorProto

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

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

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

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

// MethodDescriptorProto

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

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

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

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

// optional bool client_streaming = 5 [default = false];
inline bool MethodDescriptorProto::has_client_streaming() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void MethodDescriptorProto::set_has_client_streaming() {
  _has_bits_[0] |= 0x00000010u;
}
inline void MethodDescriptorProto::clear_has_client_streaming() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void MethodDescriptorProto::clear_client_streaming() {
  client_streaming_ = false;
  clear_has_client_streaming();
}
inline bool MethodDescriptorProto::client_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming)
  return client_streaming_;
}
inline void MethodDescriptorProto::set_client_streaming(bool value) {
  set_has_client_streaming();
  client_streaming_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming)
}

// optional bool server_streaming = 6 [default = false];
inline bool MethodDescriptorProto::has_server_streaming() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void MethodDescriptorProto::set_has_server_streaming() {
  _has_bits_[0] |= 0x00000020u;
}
inline void MethodDescriptorProto::clear_has_server_streaming() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void MethodDescriptorProto::clear_server_streaming() {
  server_streaming_ = false;
  clear_has_server_streaming();
}
inline bool MethodDescriptorProto::server_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.server_streaming)
  return server_streaming_;
}
inline void MethodDescriptorProto::set_server_streaming(bool value) {
  set_has_server_streaming();
  server_streaming_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming)
}

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

// 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() {
  java_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_java_package();
}
inline const ::std::string& FileOptions::java_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
  return java_package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_java_package(const ::std::string& value) {
  set_has_java_package();
  java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
}
inline void FileOptions::set_java_package(const char* value) {
  set_has_java_package();
  java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
}
inline void FileOptions::set_java_package(const char* value, size_t size) {
  set_has_java_package();
  java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
}
inline ::std::string* FileOptions::mutable_java_package() {
  set_has_java_package();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
  return java_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_java_package() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package)
  clear_has_java_package();
  return java_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
  if (java_package != NULL) {
    set_has_java_package();
  } else {
    clear_has_java_package();
  }
  java_package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_package);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
}

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

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

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

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

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

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

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

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

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

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

// optional bool cc_enable_arenas = 31 [default = false];
inline bool FileOptions::has_cc_enable_arenas() const {
  return (_has_bits_[0] & 0x00000800u) != 0;
}
inline void FileOptions::set_has_cc_enable_arenas() {
  _has_bits_[0] |= 0x00000800u;
}
inline void FileOptions::clear_has_cc_enable_arenas() {
  _has_bits_[0] &= ~0x00000800u;
}
inline void FileOptions::clear_cc_enable_arenas() {
  cc_enable_arenas_ = false;
  clear_has_cc_enable_arenas();
}
inline bool FileOptions::cc_enable_arenas() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas)
  return cc_enable_arenas_;
}
inline void FileOptions::set_cc_enable_arenas(bool value) {
  set_has_cc_enable_arenas();
  cc_enable_arenas_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
}

// optional string objc_class_prefix = 36;
inline bool FileOptions::has_objc_class_prefix() const {
  return (_has_bits_[0] & 0x00001000u) != 0;
}
inline void FileOptions::set_has_objc_class_prefix() {
  _has_bits_[0] |= 0x00001000u;
}
inline void FileOptions::clear_has_objc_class_prefix() {
  _has_bits_[0] &= ~0x00001000u;
}
inline void FileOptions::clear_objc_class_prefix() {
  objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_objc_class_prefix();
}
inline const ::std::string& FileOptions::objc_class_prefix() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix)
  return objc_class_prefix_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_objc_class_prefix(const ::std::string& value) {
  set_has_objc_class_prefix();
  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
}
inline void FileOptions::set_objc_class_prefix(const char* value) {
  set_has_objc_class_prefix();
  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix)
}
inline void FileOptions::set_objc_class_prefix(const char* value, size_t size) {
  set_has_objc_class_prefix();
  objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix)
}
inline ::std::string* FileOptions::mutable_objc_class_prefix() {
  set_has_objc_class_prefix();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix)
  return objc_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_objc_class_prefix() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix)
  clear_has_objc_class_prefix();
  return objc_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_class_prefix) {
  if (objc_class_prefix != NULL) {
    set_has_objc_class_prefix();
  } else {
    clear_has_objc_class_prefix();
  }
  objc_class_prefix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), objc_class_prefix);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
}

// optional string csharp_namespace = 37;
inline bool FileOptions::has_csharp_namespace() const {
  return (_has_bits_[0] & 0x00002000u) != 0;
}
inline void FileOptions::set_has_csharp_namespace() {
  _has_bits_[0] |= 0x00002000u;
}
inline void FileOptions::clear_has_csharp_namespace() {
  _has_bits_[0] &= ~0x00002000u;
}
inline void FileOptions::clear_csharp_namespace() {
  csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_csharp_namespace();
}
inline const ::std::string& FileOptions::csharp_namespace() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace)
  return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_csharp_namespace(const ::std::string& value) {
  set_has_csharp_namespace();
  csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
}
inline void FileOptions::set_csharp_namespace(const char* value) {
  set_has_csharp_namespace();
  csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
}
inline void FileOptions::set_csharp_namespace(const char* value, size_t size) {
  set_has_csharp_namespace();
  csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace)
}
inline ::std::string* FileOptions::mutable_csharp_namespace() {
  set_has_csharp_namespace();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
  return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_csharp_namespace() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace)
  clear_has_csharp_namespace();
  return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) {
  if (csharp_namespace != NULL) {
    set_has_csharp_namespace();
  } else {
    clear_has_csharp_namespace();
  }
  csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
}

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

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

// MessageOptions

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

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

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

// optional bool map_entry = 7;
inline bool MessageOptions::has_map_entry() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void MessageOptions::set_has_map_entry() {
  _has_bits_[0] |= 0x00000008u;
}
inline void MessageOptions::clear_has_map_entry() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void MessageOptions::clear_map_entry() {
  map_entry_ = false;
  clear_has_map_entry();
}
inline bool MessageOptions::map_entry() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.map_entry)
  return map_entry_;
}
inline void MessageOptions::set_map_entry(bool value) {
  set_has_map_entry();
  map_entry_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry)
}

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

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

// FieldOptions

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

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

// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
inline bool FieldOptions::has_jstype() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FieldOptions::set_has_jstype() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FieldOptions::clear_has_jstype() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FieldOptions::clear_jstype() {
  jstype_ = 0;
  clear_has_jstype();
}
inline ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype)
  return static_cast< ::google::protobuf::FieldOptions_JSType >(jstype_);
}
inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) {
  assert(::google::protobuf::FieldOptions_JSType_IsValid(value));
  set_has_jstype();
  jstype_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype)
}

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

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

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

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

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

// EnumOptions

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

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

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

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

// EnumValueOptions

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

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

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

// ServiceOptions

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

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

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

// MethodOptions

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

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

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

// 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() {
  name_part_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_name_part();
}
inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
  return name_part_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
  set_has_name_part();
  name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
  set_has_name_part();
  name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
  set_has_name_part();
  name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
  set_has_name_part();
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
  return name_part_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
  // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part)
  clear_has_name_part();
  return name_part_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
  if (name_part != NULL) {
    set_has_name_part();
  } else {
    clear_has_name_part();
  }
  name_part_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name_part);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
}

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

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

// UninterpretedOption

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

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

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

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

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

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

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

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

// SourceCodeInfo_Location

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

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

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

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

// repeated string leading_detached_comments = 6;
inline int SourceCodeInfo_Location::leading_detached_comments_size() const {
  return leading_detached_comments_.size();
}
inline void SourceCodeInfo_Location::clear_leading_detached_comments() {
  leading_detached_comments_.Clear();
}
inline const ::std::string& SourceCodeInfo_Location::leading_detached_comments(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return leading_detached_comments_.Get(index);
}
inline ::std::string* SourceCodeInfo_Location::mutable_leading_detached_comments(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return leading_detached_comments_.Mutable(index);
}
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  leading_detached_comments_.Mutable(index)->assign(value);
}
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
  leading_detached_comments_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value, size_t size) {
  leading_detached_comments_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline ::std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return leading_detached_comments_.Add();
}
inline void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& value) {
  leading_detached_comments_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
  leading_detached_comments_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value, size_t size) {
  leading_detached_comments_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
SourceCodeInfo_Location::leading_detached_comments() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return leading_detached_comments_;
}
inline ::google::protobuf::RepeatedPtrField< ::std::string>*
SourceCodeInfo_Location::mutable_leading_detached_comments() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return &leading_detached_comments_;
}

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

// SourceCodeInfo

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

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

// GeneratedCodeInfo_Annotation

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

// optional string source_file = 2;
inline bool GeneratedCodeInfo_Annotation::has_source_file() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void GeneratedCodeInfo_Annotation::set_has_source_file() {
  _has_bits_[0] |= 0x00000002u;
}
inline void GeneratedCodeInfo_Annotation::clear_has_source_file() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void GeneratedCodeInfo_Annotation::clear_source_file() {
  source_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_source_file();
}
inline const ::std::string& GeneratedCodeInfo_Annotation::source_file() const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
  return source_file_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GeneratedCodeInfo_Annotation::set_source_file(const ::std::string& value) {
  set_has_source_file();
  source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}
inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) {
  set_has_source_file();
  source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}
inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value, size_t size) {
  set_has_source_file();
  source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}
inline ::std::string* GeneratedCodeInfo_Annotation::mutable_source_file() {
  set_has_source_file();
  // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
  return source_file_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GeneratedCodeInfo_Annotation::release_source_file() {
  // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
  clear_has_source_file();
  return source_file_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(::std::string* source_file) {
  if (source_file != NULL) {
    set_has_source_file();
  } else {
    clear_has_source_file();
  }
  source_file_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), source_file);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}

// optional int32 begin = 3;
inline bool GeneratedCodeInfo_Annotation::has_begin() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void GeneratedCodeInfo_Annotation::set_has_begin() {
  _has_bits_[0] |= 0x00000004u;
}
inline void GeneratedCodeInfo_Annotation::clear_has_begin() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void GeneratedCodeInfo_Annotation::clear_begin() {
  begin_ = 0;
  clear_has_begin();
}
inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::begin() const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin)
  return begin_;
}
inline void GeneratedCodeInfo_Annotation::set_begin(::google::protobuf::int32 value) {
  set_has_begin();
  begin_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin)
}

// optional int32 end = 4;
inline bool GeneratedCodeInfo_Annotation::has_end() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void GeneratedCodeInfo_Annotation::set_has_end() {
  _has_bits_[0] |= 0x00000008u;
}
inline void GeneratedCodeInfo_Annotation::clear_has_end() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void GeneratedCodeInfo_Annotation::clear_end() {
  end_ = 0;
  clear_has_end();
}
inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::end() const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end)
  return end_;
}
inline void GeneratedCodeInfo_Annotation::set_end(::google::protobuf::int32 value) {
  set_has_end();
  end_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end)
}

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

// GeneratedCodeInfo

// repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
inline int GeneratedCodeInfo::annotation_size() const {
  return annotation_.size();
}
inline void GeneratedCodeInfo::clear_annotation() {
  annotation_.Clear();
}
inline const ::google::protobuf::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::annotation(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.annotation)
  return annotation_.Get(index);
}
inline ::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation)
  return annotation_.Mutable(index);
}
inline ::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::add_annotation() {
  // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.annotation)
  return annotation_.Add();
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >*
GeneratedCodeInfo::mutable_annotation() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.annotation)
  return &annotation_;
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >&
GeneratedCodeInfo::annotation() const {
  // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.annotation)
  return annotation_;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

#ifndef SWIG
namespace google {
namespace protobuf {

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

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

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
