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

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3021000
#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 3021009 < 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/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto PROTOBUF_EXPORT
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fdescriptor_2eproto {
  static const uint32_t offsets[];
};
PROTOBUF_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto;
PROTOBUF_NAMESPACE_OPEN
class DescriptorProto;
struct DescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_;
class DescriptorProto_ExtensionRange;
struct DescriptorProto_ExtensionRangeDefaultTypeInternal;
PROTOBUF_EXPORT extern DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_;
class DescriptorProto_ReservedRange;
struct DescriptorProto_ReservedRangeDefaultTypeInternal;
PROTOBUF_EXPORT extern DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_;
class EnumDescriptorProto;
struct EnumDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_;
class EnumDescriptorProto_EnumReservedRange;
struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal _EnumDescriptorProto_EnumReservedRange_default_instance_;
class EnumOptions;
struct EnumOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_;
class EnumValueDescriptorProto;
struct EnumValueDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_;
class EnumValueOptions;
struct EnumValueOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_;
class ExtensionRangeOptions;
struct ExtensionRangeOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_;
class FieldDescriptorProto;
struct FieldDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_;
class FieldOptions;
struct FieldOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_;
class FileDescriptorProto;
struct FileDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_;
class FileDescriptorSet;
struct FileDescriptorSetDefaultTypeInternal;
PROTOBUF_EXPORT extern FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_;
class FileOptions;
struct FileOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern FileOptionsDefaultTypeInternal _FileOptions_default_instance_;
class GeneratedCodeInfo;
struct GeneratedCodeInfoDefaultTypeInternal;
PROTOBUF_EXPORT extern GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_;
class GeneratedCodeInfo_Annotation;
struct GeneratedCodeInfo_AnnotationDefaultTypeInternal;
PROTOBUF_EXPORT extern GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_;
class MessageOptions;
struct MessageOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_;
class MethodDescriptorProto;
struct MethodDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_;
class MethodOptions;
struct MethodOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_;
class OneofDescriptorProto;
struct OneofDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_;
class OneofOptions;
struct OneofOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_;
class ServiceDescriptorProto;
struct ServiceDescriptorProtoDefaultTypeInternal;
PROTOBUF_EXPORT extern ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_;
class ServiceOptions;
struct ServiceOptionsDefaultTypeInternal;
PROTOBUF_EXPORT extern ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_;
class SourceCodeInfo;
struct SourceCodeInfoDefaultTypeInternal;
PROTOBUF_EXPORT extern SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_;
class SourceCodeInfo_Location;
struct SourceCodeInfo_LocationDefaultTypeInternal;
PROTOBUF_EXPORT extern SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_;
class UninterpretedOption;
struct UninterpretedOptionDefaultTypeInternal;
PROTOBUF_EXPORT extern UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_;
class UninterpretedOption_NamePart;
struct UninterpretedOption_NamePartDefaultTypeInternal;
PROTOBUF_EXPORT extern UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_;
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FieldOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileDescriptorSet>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::FileOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::MessageOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MessageOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::MethodOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::OneofOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::ServiceOptions* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceOptions>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::UninterpretedOption>(Arena*);
template<> PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN

enum FieldDescriptorProto_Type : int {
  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
};
PROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value);
constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
constexpr int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
template<typename T>
inline const std::string& FieldDescriptorProto_Type_Name(T enum_t_value) {
  static_assert(::std::is_same<T, FieldDescriptorProto_Type>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function FieldDescriptorProto_Type_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    FieldDescriptorProto_Type_descriptor(), enum_t_value);
}
inline bool FieldDescriptorProto_Type_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Type* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldDescriptorProto_Type>(
    FieldDescriptorProto_Type_descriptor(), name, value);
}
enum FieldDescriptorProto_Label : int {
  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
  FieldDescriptorProto_Label_LABEL_REPEATED = 3
};
PROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
constexpr int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
template<typename T>
inline const std::string& FieldDescriptorProto_Label_Name(T enum_t_value) {
  static_assert(::std::is_same<T, FieldDescriptorProto_Label>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function FieldDescriptorProto_Label_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    FieldDescriptorProto_Label_descriptor(), enum_t_value);
}
inline bool FieldDescriptorProto_Label_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Label* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldDescriptorProto_Label>(
    FieldDescriptorProto_Label_descriptor(), name, value);
}
enum FileOptions_OptimizeMode : int {
  FileOptions_OptimizeMode_SPEED = 1,
  FileOptions_OptimizeMode_CODE_SIZE = 2,
  FileOptions_OptimizeMode_LITE_RUNTIME = 3
};
PROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value);
constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME;
constexpr int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
template<typename T>
inline const std::string& FileOptions_OptimizeMode_Name(T enum_t_value) {
  static_assert(::std::is_same<T, FileOptions_OptimizeMode>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function FileOptions_OptimizeMode_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    FileOptions_OptimizeMode_descriptor(), enum_t_value);
}
inline bool FileOptions_OptimizeMode_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FileOptions_OptimizeMode* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FileOptions_OptimizeMode>(
    FileOptions_OptimizeMode_descriptor(), name, value);
}
enum FieldOptions_CType : int {
  FieldOptions_CType_STRING = 0,
  FieldOptions_CType_CORD = 1,
  FieldOptions_CType_STRING_PIECE = 2
};
PROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
constexpr FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
constexpr FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
constexpr int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_CType_descriptor();
template<typename T>
inline const std::string& FieldOptions_CType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, FieldOptions_CType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function FieldOptions_CType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    FieldOptions_CType_descriptor(), enum_t_value);
}
inline bool FieldOptions_CType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_CType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_CType>(
    FieldOptions_CType_descriptor(), name, value);
}
enum FieldOptions_JSType : int {
  FieldOptions_JSType_JS_NORMAL = 0,
  FieldOptions_JSType_JS_STRING = 1,
  FieldOptions_JSType_JS_NUMBER = 2
};
PROTOBUF_EXPORT bool FieldOptions_JSType_IsValid(int value);
constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL;
constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER;
constexpr int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_JSType_descriptor();
template<typename T>
inline const std::string& FieldOptions_JSType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, FieldOptions_JSType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function FieldOptions_JSType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    FieldOptions_JSType_descriptor(), enum_t_value);
}
inline bool FieldOptions_JSType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_JSType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_JSType>(
    FieldOptions_JSType_descriptor(), name, value);
}
enum MethodOptions_IdempotencyLevel : int {
  MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN = 0,
  MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS = 1,
  MethodOptions_IdempotencyLevel_IDEMPOTENT = 2
};
PROTOBUF_EXPORT bool MethodOptions_IdempotencyLevel_IsValid(int value);
constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN;
constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = MethodOptions_IdempotencyLevel_IDEMPOTENT;
constexpr int MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX + 1;

PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor();
template<typename T>
inline const std::string& MethodOptions_IdempotencyLevel_Name(T enum_t_value) {
  static_assert(::std::is_same<T, MethodOptions_IdempotencyLevel>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function MethodOptions_IdempotencyLevel_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    MethodOptions_IdempotencyLevel_descriptor(), enum_t_value);
}
inline bool MethodOptions_IdempotencyLevel_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, MethodOptions_IdempotencyLevel* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<MethodOptions_IdempotencyLevel>(
    MethodOptions_IdempotencyLevel_descriptor(), name, value);
}
// ===================================================================

class PROTOBUF_EXPORT FileDescriptorSet final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ {
 public:
  inline FileDescriptorSet() : FileDescriptorSet(nullptr) {}
  ~FileDescriptorSet() override;
  explicit PROTOBUF_CONSTEXPR FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FileDescriptorSet(const FileDescriptorSet& from);
  FileDescriptorSet(FileDescriptorSet&& from) noexcept
    : FileDescriptorSet() {
    *this = ::std::move(from);
  }

  inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
    CopyFrom(from);
    return *this;
  }
  inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FileDescriptorSet& default_instance() {
    return *internal_default_instance();
  }
  static inline const FileDescriptorSet* internal_default_instance() {
    return reinterpret_cast<const FileDescriptorSet*>(
               &_FileDescriptorSet_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(FileDescriptorSet& a, FileDescriptorSet& b) {
    a.Swap(&b);
  }
  inline void Swap(FileDescriptorSet* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FileDescriptorSet* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  FileDescriptorSet* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<FileDescriptorSet>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const FileDescriptorSet& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const FileDescriptorSet& from) {
    FileDescriptorSet::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FileDescriptorSet* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.FileDescriptorSet";
  }
  protected:
  explicit FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kFileFieldNumber = 1,
  };
  // repeated .google.protobuf.FileDescriptorProto file = 1;
  int file_size() const;
  private:
  int _internal_file_size() const;
  public:
  void clear_file();
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* mutable_file(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
      mutable_file();
  private:
  const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& _internal_file(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _internal_add_file();
  public:
  const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& file(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* add_file();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
      file() const;

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

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > file_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FileDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ {
 public:
  inline FileDescriptorProto() : FileDescriptorProto(nullptr) {}
  ~FileDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FileDescriptorProto(const FileDescriptorProto& from);
  FileDescriptorProto(FileDescriptorProto&& from) noexcept
    : FileDescriptorProto() {
    *this = ::std::move(from);
  }

  inline FileDescriptorProto& operator=(const FileDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FileDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const FileDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const FileDescriptorProto*>(
               &_FileDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(FileDescriptorProto& a, FileDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(FileDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FileDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  FileDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<FileDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const FileDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const FileDescriptorProto& from) {
    FileDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FileDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.FileDescriptorProto";
  }
  protected:
  explicit FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kDependencyFieldNumber = 3,
    kMessageTypeFieldNumber = 4,
    kEnumTypeFieldNumber = 5,
    kServiceFieldNumber = 6,
    kExtensionFieldNumber = 7,
    kPublicDependencyFieldNumber = 10,
    kWeakDependencyFieldNumber = 11,
    kNameFieldNumber = 1,
    kPackageFieldNumber = 2,
    kSyntaxFieldNumber = 12,
    kOptionsFieldNumber = 8,
    kSourceCodeInfoFieldNumber = 9,
  };
  // repeated string dependency = 3;
  int dependency_size() const;
  private:
  int _internal_dependency_size() const;
  public:
  void clear_dependency();
  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, 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(std::string&& value);
  void add_dependency(const char* value);
  void add_dependency(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& dependency() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_dependency();
  private:
  const std::string& _internal_dependency(int index) const;
  std::string* _internal_add_dependency();
  public:

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  int message_type_size() const;
  private:
  int _internal_message_type_size() const;
  public:
  void clear_message_type();
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto* mutable_message_type(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >*
      mutable_message_type();
  private:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& _internal_message_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _internal_add_message_type();
  public:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& message_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto* add_message_type();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >&
      message_type() const;

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  int enum_type_size() const;
  private:
  int _internal_enum_type_size() const;
  public:
  void clear_enum_type();
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* mutable_enum_type(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >*
      mutable_enum_type();
  private:
  const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& _internal_enum_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _internal_add_enum_type();
  public:
  const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& enum_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* add_enum_type();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >&
      enum_type() const;

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  int service_size() const;
  private:
  int _internal_service_size() const;
  public:
  void clear_service();
  ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* mutable_service(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >*
      mutable_service();
  private:
  const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& _internal_service(int index) const;
  ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* _internal_add_service();
  public:
  const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto& service(int index) const;
  ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto* add_service();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >&
      service() const;

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  int extension_size() const;
  private:
  int _internal_extension_size() const;
  public:
  void clear_extension();
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_extension(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
      mutable_extension();
  private:
  const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_extension(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_extension();
  public:
  const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& extension(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_extension();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
      extension() const;

  // repeated int32 public_dependency = 10;
  int public_dependency_size() const;
  private:
  int _internal_public_dependency_size() const;
  public:
  void clear_public_dependency();
  private:
  int32_t _internal_public_dependency(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      _internal_public_dependency() const;
  void _internal_add_public_dependency(int32_t value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      _internal_mutable_public_dependency();
  public:
  int32_t public_dependency(int index) const;
  void set_public_dependency(int index, int32_t value);
  void add_public_dependency(int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      public_dependency() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      mutable_public_dependency();

  // repeated int32 weak_dependency = 11;
  int weak_dependency_size() const;
  private:
  int _internal_weak_dependency_size() const;
  public:
  void clear_weak_dependency();
  private:
  int32_t _internal_weak_dependency(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      _internal_weak_dependency() const;
  void _internal_add_weak_dependency(int32_t value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      _internal_mutable_weak_dependency();
  public:
  int32_t weak_dependency(int index) const;
  void set_weak_dependency(int index, int32_t value);
  void add_weak_dependency(int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      weak_dependency() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      mutable_weak_dependency();

  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional string package = 2;
  bool has_package() const;
  private:
  bool _internal_has_package() const;
  public:
  void clear_package();
  const std::string& package() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_package(ArgT0&& arg0, ArgT... args);
  std::string* mutable_package();
  PROTOBUF_NODISCARD std::string* release_package();
  void set_allocated_package(std::string* package);
  private:
  const std::string& _internal_package() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_package(const std::string& value);
  std::string* _internal_mutable_package();
  public:

  // optional string syntax = 12;
  bool has_syntax() const;
  private:
  bool _internal_has_syntax() const;
  public:
  void clear_syntax();
  const std::string& syntax() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_syntax(ArgT0&& arg0, ArgT... args);
  std::string* mutable_syntax();
  PROTOBUF_NODISCARD std::string* release_syntax();
  void set_allocated_syntax(std::string* syntax);
  private:
  const std::string& _internal_syntax() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_syntax(const std::string& value);
  std::string* _internal_mutable_syntax();
  public:

  // optional .google.protobuf.FileOptions options = 8;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::FileOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::FileOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::FileOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::FileOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::FileOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::FileOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::FileOptions* options);
  ::PROTOBUF_NAMESPACE_ID::FileOptions* unsafe_arena_release_options();

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  bool has_source_code_info() const;
  private:
  bool _internal_has_source_code_info() const;
  public:
  void clear_source_code_info();
  const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& source_code_info() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* release_source_code_info();
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* mutable_source_code_info();
  void set_allocated_source_code_info(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info);
  private:
  const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& _internal_source_code_info() const;
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* _internal_mutable_source_code_info();
  public:
  void unsafe_arena_set_allocated_source_code_info(
      ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info);
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* unsafe_arena_release_source_code_info();

  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> dependency_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto > message_type_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto > enum_type_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto > service_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto > extension_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > public_dependency_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > weak_dependency_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr package_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr syntax_;
    ::PROTOBUF_NAMESPACE_ID::FileOptions* options_;
    ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ {
 public:
  inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {}
  ~DescriptorProto_ExtensionRange() override;
  explicit PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
  DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept
    : DescriptorProto_ExtensionRange() {
    *this = ::std::move(from);
  }

  inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) {
    CopyFrom(from);
    return *this;
  }
  inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const DescriptorProto_ExtensionRange& default_instance() {
    return *internal_default_instance();
  }
  static inline const DescriptorProto_ExtensionRange* internal_default_instance() {
    return reinterpret_cast<const DescriptorProto_ExtensionRange*>(
               &_DescriptorProto_ExtensionRange_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(DescriptorProto_ExtensionRange& a, DescriptorProto_ExtensionRange& b) {
    a.Swap(&b);
  }
  inline void Swap(DescriptorProto_ExtensionRange* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(DescriptorProto_ExtensionRange* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  DescriptorProto_ExtensionRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<DescriptorProto_ExtensionRange>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const DescriptorProto_ExtensionRange& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const DescriptorProto_ExtensionRange& from) {
    DescriptorProto_ExtensionRange::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(DescriptorProto_ExtensionRange* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.DescriptorProto.ExtensionRange";
  }
  protected:
  explicit DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kOptionsFieldNumber = 3,
    kStartFieldNumber = 1,
    kEndFieldNumber = 2,
  };
  // optional .google.protobuf.ExtensionRangeOptions options = 3;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options);
  ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* unsafe_arena_release_options();

  // optional int32 start = 1;
  bool has_start() const;
  private:
  bool _internal_has_start() const;
  public:
  void clear_start();
  int32_t start() const;
  void set_start(int32_t value);
  private:
  int32_t _internal_start() const;
  void _internal_set_start(int32_t value);
  public:

  // optional int32 end = 2;
  bool has_end() const;
  private:
  bool _internal_has_end() const;
  public:
  void clear_end();
  int32_t end() const;
  void set_end(int32_t value);
  private:
  int32_t _internal_end() const;
  void _internal_set_end(int32_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options_;
    int32_t start_;
    int32_t end_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT DescriptorProto_ReservedRange final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ {
 public:
  inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {}
  ~DescriptorProto_ReservedRange() override;
  explicit PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from);
  DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept
    : DescriptorProto_ReservedRange() {
    *this = ::std::move(from);
  }

  inline DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) {
    CopyFrom(from);
    return *this;
  }
  inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const DescriptorProto_ReservedRange& default_instance() {
    return *internal_default_instance();
  }
  static inline const DescriptorProto_ReservedRange* internal_default_instance() {
    return reinterpret_cast<const DescriptorProto_ReservedRange*>(
               &_DescriptorProto_ReservedRange_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  friend void swap(DescriptorProto_ReservedRange& a, DescriptorProto_ReservedRange& b) {
    a.Swap(&b);
  }
  inline void Swap(DescriptorProto_ReservedRange* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(DescriptorProto_ReservedRange* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  DescriptorProto_ReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<DescriptorProto_ReservedRange>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const DescriptorProto_ReservedRange& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const DescriptorProto_ReservedRange& from) {
    DescriptorProto_ReservedRange::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(DescriptorProto_ReservedRange* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.DescriptorProto.ReservedRange";
  }
  protected:
  explicit DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kStartFieldNumber = 1,
    kEndFieldNumber = 2,
  };
  // optional int32 start = 1;
  bool has_start() const;
  private:
  bool _internal_has_start() const;
  public:
  void clear_start();
  int32_t start() const;
  void set_start(int32_t value);
  private:
  int32_t _internal_start() const;
  void _internal_set_start(int32_t value);
  public:

  // optional int32 end = 2;
  bool has_end() const;
  private:
  bool _internal_has_end() const;
  public:
  void clear_end();
  int32_t end() const;
  void set_end(int32_t value);
  private:
  int32_t _internal_end() const;
  void _internal_set_end(int32_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    int32_t start_;
    int32_t end_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT DescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ {
 public:
  inline DescriptorProto() : DescriptorProto(nullptr) {}
  ~DescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR DescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  DescriptorProto(const DescriptorProto& from);
  DescriptorProto(DescriptorProto&& from) noexcept
    : DescriptorProto() {
    *this = ::std::move(from);
  }

  inline DescriptorProto& operator=(const DescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline DescriptorProto& operator=(DescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const DescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const DescriptorProto* internal_default_instance() {
    return reinterpret_cast<const DescriptorProto*>(
               &_DescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  friend void swap(DescriptorProto& a, DescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(DescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(DescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  DescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<DescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const DescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const DescriptorProto& from) {
    DescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(DescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.DescriptorProto";
  }
  protected:
  explicit DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef DescriptorProto_ExtensionRange ExtensionRange;
  typedef DescriptorProto_ReservedRange ReservedRange;

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

  enum : int {
    kFieldFieldNumber = 2,
    kNestedTypeFieldNumber = 3,
    kEnumTypeFieldNumber = 4,
    kExtensionRangeFieldNumber = 5,
    kExtensionFieldNumber = 6,
    kOneofDeclFieldNumber = 8,
    kReservedRangeFieldNumber = 9,
    kReservedNameFieldNumber = 10,
    kNameFieldNumber = 1,
    kOptionsFieldNumber = 7,
  };
  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  int field_size() const;
  private:
  int _internal_field_size() const;
  public:
  void clear_field();
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_field(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
      mutable_field();
  private:
  const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_field(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_field();
  public:
  const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& field(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_field();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
      field() const;

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  int nested_type_size() const;
  private:
  int _internal_nested_type_size() const;
  public:
  void clear_nested_type();
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto* mutable_nested_type(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >*
      mutable_nested_type();
  private:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& _internal_nested_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto* _internal_add_nested_type();
  public:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto& nested_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto* add_nested_type();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >&
      nested_type() const;

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  int enum_type_size() const;
  private:
  int _internal_enum_type_size() const;
  public:
  void clear_enum_type();
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* mutable_enum_type(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >*
      mutable_enum_type();
  private:
  const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& _internal_enum_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* _internal_add_enum_type();
  public:
  const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto& enum_type(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto* add_enum_type();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >&
      enum_type() const;

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  int extension_range_size() const;
  private:
  int _internal_extension_range_size() const;
  public:
  void clear_extension_range();
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >*
      mutable_extension_range();
  private:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& _internal_extension_range(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* _internal_add_extension_range();
  public:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange& extension_range(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange* add_extension_range();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >&
      extension_range() const;

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  int extension_size() const;
  private:
  int _internal_extension_size() const;
  public:
  void clear_extension();
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* mutable_extension(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >*
      mutable_extension();
  private:
  const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& _internal_extension(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* _internal_add_extension();
  public:
  const ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto& extension(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto* add_extension();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >&
      extension() const;

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  int oneof_decl_size() const;
  private:
  int _internal_oneof_decl_size() const;
  public:
  void clear_oneof_decl();
  ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* mutable_oneof_decl(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >*
      mutable_oneof_decl();
  private:
  const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& _internal_oneof_decl(int index) const;
  ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* _internal_add_oneof_decl();
  public:
  const ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto& oneof_decl(int index) const;
  ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto* add_oneof_decl();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >&
      oneof_decl() const;

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  int reserved_range_size() const;
  private:
  int _internal_reserved_range_size() const;
  public:
  void clear_reserved_range();
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* mutable_reserved_range(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >*
      mutable_reserved_range();
  private:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& _internal_reserved_range(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* _internal_add_reserved_range();
  public:
  const ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange& reserved_range(int index) const;
  ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange* add_reserved_range();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >&
      reserved_range() const;

  // repeated string reserved_name = 10;
  int reserved_name_size() const;
  private:
  int _internal_reserved_name_size() const;
  public:
  void clear_reserved_name();
  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, 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(std::string&& value);
  void add_reserved_name(const char* value);
  void add_reserved_name(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& reserved_name() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_reserved_name();
  private:
  const std::string& _internal_reserved_name(int index) const;
  std::string* _internal_add_reserved_name();
  public:

  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional .google.protobuf.MessageOptions options = 7;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::MessageOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::MessageOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::MessageOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::MessageOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::MessageOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::MessageOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::MessageOptions* options);
  ::PROTOBUF_NAMESPACE_ID::MessageOptions* unsafe_arena_release_options();

  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto > field_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto > nested_type_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto > enum_type_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange > extension_range_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto > extension_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto > oneof_decl_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange > reserved_range_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> reserved_name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::MessageOptions* options_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ExtensionRangeOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ {
 public:
  inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {}
  ~ExtensionRangeOptions() override;
  explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ExtensionRangeOptions(const ExtensionRangeOptions& from);
  ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept
    : ExtensionRangeOptions() {
    *this = ::std::move(from);
  }

  inline ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ExtensionRangeOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const ExtensionRangeOptions* internal_default_instance() {
    return reinterpret_cast<const ExtensionRangeOptions*>(
               &_ExtensionRangeOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    5;

  friend void swap(ExtensionRangeOptions& a, ExtensionRangeOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(ExtensionRangeOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ExtensionRangeOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  ExtensionRangeOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<ExtensionRangeOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const ExtensionRangeOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const ExtensionRangeOptions& from) {
    ExtensionRangeOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ExtensionRangeOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.ExtensionRangeOptions";
  }
  protected:
  explicit ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ExtensionRangeOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FieldDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ {
 public:
  inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {}
  ~FieldDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FieldDescriptorProto(const FieldDescriptorProto& from);
  FieldDescriptorProto(FieldDescriptorProto&& from) noexcept
    : FieldDescriptorProto() {
    *this = ::std::move(from);
  }

  inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FieldDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const FieldDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const FieldDescriptorProto*>(
               &_FieldDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    6;

  friend void swap(FieldDescriptorProto& a, FieldDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(FieldDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FieldDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  FieldDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<FieldDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const FieldDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const FieldDescriptorProto& from) {
    FieldDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FieldDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.FieldDescriptorProto";
  }
  protected:
  explicit FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef FieldDescriptorProto_Type Type;
  static constexpr Type TYPE_DOUBLE =
    FieldDescriptorProto_Type_TYPE_DOUBLE;
  static constexpr Type TYPE_FLOAT =
    FieldDescriptorProto_Type_TYPE_FLOAT;
  static constexpr Type TYPE_INT64 =
    FieldDescriptorProto_Type_TYPE_INT64;
  static constexpr Type TYPE_UINT64 =
    FieldDescriptorProto_Type_TYPE_UINT64;
  static constexpr Type TYPE_INT32 =
    FieldDescriptorProto_Type_TYPE_INT32;
  static constexpr Type TYPE_FIXED64 =
    FieldDescriptorProto_Type_TYPE_FIXED64;
  static constexpr Type TYPE_FIXED32 =
    FieldDescriptorProto_Type_TYPE_FIXED32;
  static constexpr Type TYPE_BOOL =
    FieldDescriptorProto_Type_TYPE_BOOL;
  static constexpr Type TYPE_STRING =
    FieldDescriptorProto_Type_TYPE_STRING;
  static constexpr Type TYPE_GROUP =
    FieldDescriptorProto_Type_TYPE_GROUP;
  static constexpr Type TYPE_MESSAGE =
    FieldDescriptorProto_Type_TYPE_MESSAGE;
  static constexpr Type TYPE_BYTES =
    FieldDescriptorProto_Type_TYPE_BYTES;
  static constexpr Type TYPE_UINT32 =
    FieldDescriptorProto_Type_TYPE_UINT32;
  static constexpr Type TYPE_ENUM =
    FieldDescriptorProto_Type_TYPE_ENUM;
  static constexpr Type TYPE_SFIXED32 =
    FieldDescriptorProto_Type_TYPE_SFIXED32;
  static constexpr Type TYPE_SFIXED64 =
    FieldDescriptorProto_Type_TYPE_SFIXED64;
  static constexpr Type TYPE_SINT32 =
    FieldDescriptorProto_Type_TYPE_SINT32;
  static constexpr Type TYPE_SINT64 =
    FieldDescriptorProto_Type_TYPE_SINT64;
  static inline bool Type_IsValid(int value) {
    return FieldDescriptorProto_Type_IsValid(value);
  }
  static constexpr Type Type_MIN =
    FieldDescriptorProto_Type_Type_MIN;
  static constexpr Type Type_MAX =
    FieldDescriptorProto_Type_Type_MAX;
  static constexpr int Type_ARRAYSIZE =
    FieldDescriptorProto_Type_Type_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  Type_descriptor() {
    return FieldDescriptorProto_Type_descriptor();
  }
  template<typename T>
  static inline const std::string& Type_Name(T enum_t_value) {
    static_assert(::std::is_same<T, Type>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function Type_Name.");
    return FieldDescriptorProto_Type_Name(enum_t_value);
  }
  static inline bool Type_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      Type* value) {
    return FieldDescriptorProto_Type_Parse(name, value);
  }

  typedef FieldDescriptorProto_Label Label;
  static constexpr Label LABEL_OPTIONAL =
    FieldDescriptorProto_Label_LABEL_OPTIONAL;
  static constexpr Label LABEL_REQUIRED =
    FieldDescriptorProto_Label_LABEL_REQUIRED;
  static constexpr Label LABEL_REPEATED =
    FieldDescriptorProto_Label_LABEL_REPEATED;
  static inline bool Label_IsValid(int value) {
    return FieldDescriptorProto_Label_IsValid(value);
  }
  static constexpr Label Label_MIN =
    FieldDescriptorProto_Label_Label_MIN;
  static constexpr Label Label_MAX =
    FieldDescriptorProto_Label_Label_MAX;
  static constexpr int Label_ARRAYSIZE =
    FieldDescriptorProto_Label_Label_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  Label_descriptor() {
    return FieldDescriptorProto_Label_descriptor();
  }
  template<typename T>
  static inline const std::string& Label_Name(T enum_t_value) {
    static_assert(::std::is_same<T, Label>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function Label_Name.");
    return FieldDescriptorProto_Label_Name(enum_t_value);
  }
  static inline bool Label_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      Label* value) {
    return FieldDescriptorProto_Label_Parse(name, value);
  }

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

  enum : int {
    kNameFieldNumber = 1,
    kExtendeeFieldNumber = 2,
    kTypeNameFieldNumber = 6,
    kDefaultValueFieldNumber = 7,
    kJsonNameFieldNumber = 10,
    kOptionsFieldNumber = 8,
    kNumberFieldNumber = 3,
    kOneofIndexFieldNumber = 9,
    kProto3OptionalFieldNumber = 17,
    kLabelFieldNumber = 4,
    kTypeFieldNumber = 5,
  };
  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional string extendee = 2;
  bool has_extendee() const;
  private:
  bool _internal_has_extendee() const;
  public:
  void clear_extendee();
  const std::string& extendee() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_extendee(ArgT0&& arg0, ArgT... args);
  std::string* mutable_extendee();
  PROTOBUF_NODISCARD std::string* release_extendee();
  void set_allocated_extendee(std::string* extendee);
  private:
  const std::string& _internal_extendee() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_extendee(const std::string& value);
  std::string* _internal_mutable_extendee();
  public:

  // optional string type_name = 6;
  bool has_type_name() const;
  private:
  bool _internal_has_type_name() const;
  public:
  void clear_type_name();
  const std::string& type_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_type_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_type_name();
  PROTOBUF_NODISCARD std::string* release_type_name();
  void set_allocated_type_name(std::string* type_name);
  private:
  const std::string& _internal_type_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_type_name(const std::string& value);
  std::string* _internal_mutable_type_name();
  public:

  // optional string default_value = 7;
  bool has_default_value() const;
  private:
  bool _internal_has_default_value() const;
  public:
  void clear_default_value();
  const std::string& default_value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_default_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_default_value();
  PROTOBUF_NODISCARD std::string* release_default_value();
  void set_allocated_default_value(std::string* default_value);
  private:
  const std::string& _internal_default_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_default_value(const std::string& value);
  std::string* _internal_mutable_default_value();
  public:

  // optional string json_name = 10;
  bool has_json_name() const;
  private:
  bool _internal_has_json_name() const;
  public:
  void clear_json_name();
  const std::string& json_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_json_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_json_name();
  PROTOBUF_NODISCARD std::string* release_json_name();
  void set_allocated_json_name(std::string* json_name);
  private:
  const std::string& _internal_json_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_json_name(const std::string& value);
  std::string* _internal_mutable_json_name();
  public:

  // optional .google.protobuf.FieldOptions options = 8;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::FieldOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::FieldOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::FieldOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::FieldOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::FieldOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::FieldOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::FieldOptions* options);
  ::PROTOBUF_NAMESPACE_ID::FieldOptions* unsafe_arena_release_options();

  // optional int32 number = 3;
  bool has_number() const;
  private:
  bool _internal_has_number() const;
  public:
  void clear_number();
  int32_t number() const;
  void set_number(int32_t value);
  private:
  int32_t _internal_number() const;
  void _internal_set_number(int32_t value);
  public:

  // optional int32 oneof_index = 9;
  bool has_oneof_index() const;
  private:
  bool _internal_has_oneof_index() const;
  public:
  void clear_oneof_index();
  int32_t oneof_index() const;
  void set_oneof_index(int32_t value);
  private:
  int32_t _internal_oneof_index() const;
  void _internal_set_oneof_index(int32_t value);
  public:

  // optional bool proto3_optional = 17;
  bool has_proto3_optional() const;
  private:
  bool _internal_has_proto3_optional() const;
  public:
  void clear_proto3_optional();
  bool proto3_optional() const;
  void set_proto3_optional(bool value);
  private:
  bool _internal_proto3_optional() const;
  void _internal_set_proto3_optional(bool value);
  public:

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  bool has_label() const;
  private:
  bool _internal_has_label() const;
  public:
  void clear_label();
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label label() const;
  void set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value);
  private:
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label _internal_label() const;
  void _internal_set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value);
  public:

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type type() const;
  void set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value);
  private:
  ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type _internal_type() const;
  void _internal_set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr extendee_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr default_value_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr json_name_;
    ::PROTOBUF_NAMESPACE_ID::FieldOptions* options_;
    int32_t number_;
    int32_t oneof_index_;
    bool proto3_optional_;
    int label_;
    int type_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT OneofDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ {
 public:
  inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {}
  ~OneofDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  OneofDescriptorProto(const OneofDescriptorProto& from);
  OneofDescriptorProto(OneofDescriptorProto&& from) noexcept
    : OneofDescriptorProto() {
    *this = ::std::move(from);
  }

  inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const OneofDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const OneofDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const OneofDescriptorProto*>(
               &_OneofDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    7;

  friend void swap(OneofDescriptorProto& a, OneofDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(OneofDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(OneofDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  OneofDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<OneofDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const OneofDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const OneofDescriptorProto& from) {
    OneofDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(OneofDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.OneofDescriptorProto";
  }
  protected:
  explicit OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kNameFieldNumber = 1,
    kOptionsFieldNumber = 2,
  };
  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional .google.protobuf.OneofOptions options = 2;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::OneofOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::OneofOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::OneofOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::OneofOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::OneofOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::OneofOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::OneofOptions* options);
  ::PROTOBUF_NAMESPACE_ID::OneofOptions* unsafe_arena_release_options();

  // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::OneofOptions* options_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ {
 public:
  inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {}
  ~EnumDescriptorProto_EnumReservedRange() override;
  explicit PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from);
  EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept
    : EnumDescriptorProto_EnumReservedRange() {
    *this = ::std::move(from);
  }

  inline EnumDescriptorProto_EnumReservedRange& operator=(const EnumDescriptorProto_EnumReservedRange& from) {
    CopyFrom(from);
    return *this;
  }
  inline EnumDescriptorProto_EnumReservedRange& operator=(EnumDescriptorProto_EnumReservedRange&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const EnumDescriptorProto_EnumReservedRange& default_instance() {
    return *internal_default_instance();
  }
  static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() {
    return reinterpret_cast<const EnumDescriptorProto_EnumReservedRange*>(
               &_EnumDescriptorProto_EnumReservedRange_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    8;

  friend void swap(EnumDescriptorProto_EnumReservedRange& a, EnumDescriptorProto_EnumReservedRange& b) {
    a.Swap(&b);
  }
  inline void Swap(EnumDescriptorProto_EnumReservedRange* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  EnumDescriptorProto_EnumReservedRange* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<EnumDescriptorProto_EnumReservedRange>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const EnumDescriptorProto_EnumReservedRange& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const EnumDescriptorProto_EnumReservedRange& from) {
    EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumDescriptorProto_EnumReservedRange* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.EnumDescriptorProto.EnumReservedRange";
  }
  protected:
  explicit EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kStartFieldNumber = 1,
    kEndFieldNumber = 2,
  };
  // optional int32 start = 1;
  bool has_start() const;
  private:
  bool _internal_has_start() const;
  public:
  void clear_start();
  int32_t start() const;
  void set_start(int32_t value);
  private:
  int32_t _internal_start() const;
  void _internal_set_start(int32_t value);
  public:

  // optional int32 end = 2;
  bool has_end() const;
  private:
  bool _internal_has_end() const;
  public:
  void clear_end();
  int32_t end() const;
  void set_end(int32_t value);
  private:
  int32_t _internal_end() const;
  void _internal_set_end(int32_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto.EnumReservedRange)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    int32_t start_;
    int32_t end_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ {
 public:
  inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {}
  ~EnumDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  EnumDescriptorProto(const EnumDescriptorProto& from);
  EnumDescriptorProto(EnumDescriptorProto&& from) noexcept
    : EnumDescriptorProto() {
    *this = ::std::move(from);
  }

  inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const EnumDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const EnumDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const EnumDescriptorProto*>(
               &_EnumDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    9;

  friend void swap(EnumDescriptorProto& a, EnumDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(EnumDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  EnumDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<EnumDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const EnumDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const EnumDescriptorProto& from) {
    EnumDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.EnumDescriptorProto";
  }
  protected:
  explicit EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef EnumDescriptorProto_EnumReservedRange EnumReservedRange;

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

  enum : int {
    kValueFieldNumber = 2,
    kReservedRangeFieldNumber = 4,
    kReservedNameFieldNumber = 5,
    kNameFieldNumber = 1,
    kOptionsFieldNumber = 3,
  };
  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  int value_size() const;
  private:
  int _internal_value_size() const;
  public:
  void clear_value();
  ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* mutable_value(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >*
      mutable_value();
  private:
  const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& _internal_value(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* _internal_add_value();
  public:
  const ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto& value(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto* add_value();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >&
      value() const;

  // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
  int reserved_range_size() const;
  private:
  int _internal_reserved_range_size() const;
  public:
  void clear_reserved_range();
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* mutable_reserved_range(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >*
      mutable_reserved_range();
  private:
  const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& _internal_reserved_range(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* _internal_add_reserved_range();
  public:
  const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& reserved_range(int index) const;
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* add_reserved_range();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >&
      reserved_range() const;

  // repeated string reserved_name = 5;
  int reserved_name_size() const;
  private:
  int _internal_reserved_name_size() const;
  public:
  void clear_reserved_name();
  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, 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(std::string&& value);
  void add_reserved_name(const char* value);
  void add_reserved_name(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& reserved_name() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_reserved_name();
  private:
  const std::string& _internal_reserved_name(int index) const;
  std::string* _internal_add_reserved_name();
  public:

  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional .google.protobuf.EnumOptions options = 3;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::EnumOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::EnumOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::EnumOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::EnumOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::EnumOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::EnumOptions* options);
  ::PROTOBUF_NAMESPACE_ID::EnumOptions* unsafe_arena_release_options();

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto > value_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange > reserved_range_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> reserved_name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::EnumOptions* options_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumValueDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ {
 public:
  inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {}
  ~EnumValueDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
  EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept
    : EnumValueDescriptorProto() {
    *this = ::std::move(from);
  }

  inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const EnumValueDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const EnumValueDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const EnumValueDescriptorProto*>(
               &_EnumValueDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    10;

  friend void swap(EnumValueDescriptorProto& a, EnumValueDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(EnumValueDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumValueDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  EnumValueDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<EnumValueDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const EnumValueDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const EnumValueDescriptorProto& from) {
    EnumValueDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumValueDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.EnumValueDescriptorProto";
  }
  protected:
  explicit EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kNameFieldNumber = 1,
    kOptionsFieldNumber = 3,
    kNumberFieldNumber = 2,
  };
  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional .google.protobuf.EnumValueOptions options = 3;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options);
  ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* unsafe_arena_release_options();

  // optional int32 number = 2;
  bool has_number() const;
  private:
  bool _internal_has_number() const;
  public:
  void clear_number();
  int32_t number() const;
  void set_number(int32_t value);
  private:
  int32_t _internal_number() const;
  void _internal_set_number(int32_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options_;
    int32_t number_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ServiceDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ {
 public:
  inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {}
  ~ServiceDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ServiceDescriptorProto(const ServiceDescriptorProto& from);
  ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept
    : ServiceDescriptorProto() {
    *this = ::std::move(from);
  }

  inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ServiceDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const ServiceDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const ServiceDescriptorProto*>(
               &_ServiceDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    11;

  friend void swap(ServiceDescriptorProto& a, ServiceDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(ServiceDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ServiceDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  ServiceDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<ServiceDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const ServiceDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const ServiceDescriptorProto& from) {
    ServiceDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ServiceDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.ServiceDescriptorProto";
  }
  protected:
  explicit ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kMethodFieldNumber = 2,
    kNameFieldNumber = 1,
    kOptionsFieldNumber = 3,
  };
  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  int method_size() const;
  private:
  int _internal_method_size() const;
  public:
  void clear_method();
  ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* mutable_method(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >*
      mutable_method();
  private:
  const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& _internal_method(int index) const;
  ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* _internal_add_method();
  public:
  const ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto& method(int index) const;
  ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto* add_method();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >&
      method() const;

  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional .google.protobuf.ServiceOptions options = 3;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::ServiceOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::ServiceOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::ServiceOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::ServiceOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options);
  ::PROTOBUF_NAMESPACE_ID::ServiceOptions* unsafe_arena_release_options();

  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto > method_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT MethodDescriptorProto final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ {
 public:
  inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {}
  ~MethodDescriptorProto() override;
  explicit PROTOBUF_CONSTEXPR MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  MethodDescriptorProto(const MethodDescriptorProto& from);
  MethodDescriptorProto(MethodDescriptorProto&& from) noexcept
    : MethodDescriptorProto() {
    *this = ::std::move(from);
  }

  inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) {
    CopyFrom(from);
    return *this;
  }
  inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const MethodDescriptorProto& default_instance() {
    return *internal_default_instance();
  }
  static inline const MethodDescriptorProto* internal_default_instance() {
    return reinterpret_cast<const MethodDescriptorProto*>(
               &_MethodDescriptorProto_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    12;

  friend void swap(MethodDescriptorProto& a, MethodDescriptorProto& b) {
    a.Swap(&b);
  }
  inline void Swap(MethodDescriptorProto* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MethodDescriptorProto* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  MethodDescriptorProto* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<MethodDescriptorProto>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const MethodDescriptorProto& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const MethodDescriptorProto& from) {
    MethodDescriptorProto::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MethodDescriptorProto* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.MethodDescriptorProto";
  }
  protected:
  explicit MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kNameFieldNumber = 1,
    kInputTypeFieldNumber = 2,
    kOutputTypeFieldNumber = 3,
    kOptionsFieldNumber = 4,
    kClientStreamingFieldNumber = 5,
    kServerStreamingFieldNumber = 6,
  };
  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional string input_type = 2;
  bool has_input_type() const;
  private:
  bool _internal_has_input_type() const;
  public:
  void clear_input_type();
  const std::string& input_type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_input_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_input_type();
  PROTOBUF_NODISCARD std::string* release_input_type();
  void set_allocated_input_type(std::string* input_type);
  private:
  const std::string& _internal_input_type() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_input_type(const std::string& value);
  std::string* _internal_mutable_input_type();
  public:

  // optional string output_type = 3;
  bool has_output_type() const;
  private:
  bool _internal_has_output_type() const;
  public:
  void clear_output_type();
  const std::string& output_type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_output_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_output_type();
  PROTOBUF_NODISCARD std::string* release_output_type();
  void set_allocated_output_type(std::string* output_type);
  private:
  const std::string& _internal_output_type() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_output_type(const std::string& value);
  std::string* _internal_mutable_output_type();
  public:

  // optional .google.protobuf.MethodOptions options = 4;
  bool has_options() const;
  private:
  bool _internal_has_options() const;
  public:
  void clear_options();
  const ::PROTOBUF_NAMESPACE_ID::MethodOptions& options() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::MethodOptions* release_options();
  ::PROTOBUF_NAMESPACE_ID::MethodOptions* mutable_options();
  void set_allocated_options(::PROTOBUF_NAMESPACE_ID::MethodOptions* options);
  private:
  const ::PROTOBUF_NAMESPACE_ID::MethodOptions& _internal_options() const;
  ::PROTOBUF_NAMESPACE_ID::MethodOptions* _internal_mutable_options();
  public:
  void unsafe_arena_set_allocated_options(
      ::PROTOBUF_NAMESPACE_ID::MethodOptions* options);
  ::PROTOBUF_NAMESPACE_ID::MethodOptions* unsafe_arena_release_options();

  // optional bool client_streaming = 5 [default = false];
  bool has_client_streaming() const;
  private:
  bool _internal_has_client_streaming() const;
  public:
  void clear_client_streaming();
  bool client_streaming() const;
  void set_client_streaming(bool value);
  private:
  bool _internal_client_streaming() const;
  void _internal_set_client_streaming(bool value);
  public:

  // optional bool server_streaming = 6 [default = false];
  bool has_server_streaming() const;
  private:
  bool _internal_has_server_streaming() const;
  public:
  void clear_server_streaming();
  bool server_streaming() const;
  void set_server_streaming(bool value);
  private:
  bool _internal_server_streaming() const;
  void _internal_set_server_streaming(bool value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr input_type_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr output_type_;
    ::PROTOBUF_NAMESPACE_ID::MethodOptions* options_;
    bool client_streaming_;
    bool server_streaming_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FileOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ {
 public:
  inline FileOptions() : FileOptions(nullptr) {}
  ~FileOptions() override;
  explicit PROTOBUF_CONSTEXPR FileOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FileOptions(const FileOptions& from);
  FileOptions(FileOptions&& from) noexcept
    : FileOptions() {
    *this = ::std::move(from);
  }

  inline FileOptions& operator=(const FileOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline FileOptions& operator=(FileOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FileOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const FileOptions* internal_default_instance() {
    return reinterpret_cast<const FileOptions*>(
               &_FileOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    13;

  friend void swap(FileOptions& a, FileOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(FileOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FileOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  FileOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<FileOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const FileOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const FileOptions& from) {
    FileOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FileOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.FileOptions";
  }
  protected:
  explicit FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef FileOptions_OptimizeMode OptimizeMode;
  static constexpr OptimizeMode SPEED =
    FileOptions_OptimizeMode_SPEED;
  static constexpr OptimizeMode CODE_SIZE =
    FileOptions_OptimizeMode_CODE_SIZE;
  static constexpr OptimizeMode LITE_RUNTIME =
    FileOptions_OptimizeMode_LITE_RUNTIME;
  static inline bool OptimizeMode_IsValid(int value) {
    return FileOptions_OptimizeMode_IsValid(value);
  }
  static constexpr OptimizeMode OptimizeMode_MIN =
    FileOptions_OptimizeMode_OptimizeMode_MIN;
  static constexpr OptimizeMode OptimizeMode_MAX =
    FileOptions_OptimizeMode_OptimizeMode_MAX;
  static constexpr int OptimizeMode_ARRAYSIZE =
    FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  OptimizeMode_descriptor() {
    return FileOptions_OptimizeMode_descriptor();
  }
  template<typename T>
  static inline const std::string& OptimizeMode_Name(T enum_t_value) {
    static_assert(::std::is_same<T, OptimizeMode>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function OptimizeMode_Name.");
    return FileOptions_OptimizeMode_Name(enum_t_value);
  }
  static inline bool OptimizeMode_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      OptimizeMode* value) {
    return FileOptions_OptimizeMode_Parse(name, value);
  }

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kJavaPackageFieldNumber = 1,
    kJavaOuterClassnameFieldNumber = 8,
    kGoPackageFieldNumber = 11,
    kObjcClassPrefixFieldNumber = 36,
    kCsharpNamespaceFieldNumber = 37,
    kSwiftPrefixFieldNumber = 39,
    kPhpClassPrefixFieldNumber = 40,
    kPhpNamespaceFieldNumber = 41,
    kPhpMetadataNamespaceFieldNumber = 44,
    kRubyPackageFieldNumber = 45,
    kJavaMultipleFilesFieldNumber = 10,
    kJavaGenerateEqualsAndHashFieldNumber = 20,
    kJavaStringCheckUtf8FieldNumber = 27,
    kCcGenericServicesFieldNumber = 16,
    kJavaGenericServicesFieldNumber = 17,
    kPyGenericServicesFieldNumber = 18,
    kPhpGenericServicesFieldNumber = 42,
    kDeprecatedFieldNumber = 23,
    kOptimizeForFieldNumber = 9,
    kCcEnableArenasFieldNumber = 31,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional string java_package = 1;
  bool has_java_package() const;
  private:
  bool _internal_has_java_package() const;
  public:
  void clear_java_package();
  const std::string& java_package() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_java_package(ArgT0&& arg0, ArgT... args);
  std::string* mutable_java_package();
  PROTOBUF_NODISCARD std::string* release_java_package();
  void set_allocated_java_package(std::string* java_package);
  private:
  const std::string& _internal_java_package() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_java_package(const std::string& value);
  std::string* _internal_mutable_java_package();
  public:

  // optional string java_outer_classname = 8;
  bool has_java_outer_classname() const;
  private:
  bool _internal_has_java_outer_classname() const;
  public:
  void clear_java_outer_classname();
  const std::string& java_outer_classname() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_java_outer_classname(ArgT0&& arg0, ArgT... args);
  std::string* mutable_java_outer_classname();
  PROTOBUF_NODISCARD std::string* release_java_outer_classname();
  void set_allocated_java_outer_classname(std::string* java_outer_classname);
  private:
  const std::string& _internal_java_outer_classname() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_java_outer_classname(const std::string& value);
  std::string* _internal_mutable_java_outer_classname();
  public:

  // optional string go_package = 11;
  bool has_go_package() const;
  private:
  bool _internal_has_go_package() const;
  public:
  void clear_go_package();
  const std::string& go_package() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_go_package(ArgT0&& arg0, ArgT... args);
  std::string* mutable_go_package();
  PROTOBUF_NODISCARD std::string* release_go_package();
  void set_allocated_go_package(std::string* go_package);
  private:
  const std::string& _internal_go_package() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_go_package(const std::string& value);
  std::string* _internal_mutable_go_package();
  public:

  // optional string objc_class_prefix = 36;
  bool has_objc_class_prefix() const;
  private:
  bool _internal_has_objc_class_prefix() const;
  public:
  void clear_objc_class_prefix();
  const std::string& objc_class_prefix() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_objc_class_prefix(ArgT0&& arg0, ArgT... args);
  std::string* mutable_objc_class_prefix();
  PROTOBUF_NODISCARD std::string* release_objc_class_prefix();
  void set_allocated_objc_class_prefix(std::string* objc_class_prefix);
  private:
  const std::string& _internal_objc_class_prefix() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_objc_class_prefix(const std::string& value);
  std::string* _internal_mutable_objc_class_prefix();
  public:

  // optional string csharp_namespace = 37;
  bool has_csharp_namespace() const;
  private:
  bool _internal_has_csharp_namespace() const;
  public:
  void clear_csharp_namespace();
  const std::string& csharp_namespace() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_csharp_namespace(ArgT0&& arg0, ArgT... args);
  std::string* mutable_csharp_namespace();
  PROTOBUF_NODISCARD std::string* release_csharp_namespace();
  void set_allocated_csharp_namespace(std::string* csharp_namespace);
  private:
  const std::string& _internal_csharp_namespace() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_csharp_namespace(const std::string& value);
  std::string* _internal_mutable_csharp_namespace();
  public:

  // optional string swift_prefix = 39;
  bool has_swift_prefix() const;
  private:
  bool _internal_has_swift_prefix() const;
  public:
  void clear_swift_prefix();
  const std::string& swift_prefix() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_swift_prefix(ArgT0&& arg0, ArgT... args);
  std::string* mutable_swift_prefix();
  PROTOBUF_NODISCARD std::string* release_swift_prefix();
  void set_allocated_swift_prefix(std::string* swift_prefix);
  private:
  const std::string& _internal_swift_prefix() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_swift_prefix(const std::string& value);
  std::string* _internal_mutable_swift_prefix();
  public:

  // optional string php_class_prefix = 40;
  bool has_php_class_prefix() const;
  private:
  bool _internal_has_php_class_prefix() const;
  public:
  void clear_php_class_prefix();
  const std::string& php_class_prefix() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_php_class_prefix(ArgT0&& arg0, ArgT... args);
  std::string* mutable_php_class_prefix();
  PROTOBUF_NODISCARD std::string* release_php_class_prefix();
  void set_allocated_php_class_prefix(std::string* php_class_prefix);
  private:
  const std::string& _internal_php_class_prefix() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_class_prefix(const std::string& value);
  std::string* _internal_mutable_php_class_prefix();
  public:

  // optional string php_namespace = 41;
  bool has_php_namespace() const;
  private:
  bool _internal_has_php_namespace() const;
  public:
  void clear_php_namespace();
  const std::string& php_namespace() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_php_namespace(ArgT0&& arg0, ArgT... args);
  std::string* mutable_php_namespace();
  PROTOBUF_NODISCARD std::string* release_php_namespace();
  void set_allocated_php_namespace(std::string* php_namespace);
  private:
  const std::string& _internal_php_namespace() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_namespace(const std::string& value);
  std::string* _internal_mutable_php_namespace();
  public:

  // optional string php_metadata_namespace = 44;
  bool has_php_metadata_namespace() const;
  private:
  bool _internal_has_php_metadata_namespace() const;
  public:
  void clear_php_metadata_namespace();
  const std::string& php_metadata_namespace() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_php_metadata_namespace(ArgT0&& arg0, ArgT... args);
  std::string* mutable_php_metadata_namespace();
  PROTOBUF_NODISCARD std::string* release_php_metadata_namespace();
  void set_allocated_php_metadata_namespace(std::string* php_metadata_namespace);
  private:
  const std::string& _internal_php_metadata_namespace() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_php_metadata_namespace(const std::string& value);
  std::string* _internal_mutable_php_metadata_namespace();
  public:

  // optional string ruby_package = 45;
  bool has_ruby_package() const;
  private:
  bool _internal_has_ruby_package() const;
  public:
  void clear_ruby_package();
  const std::string& ruby_package() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_ruby_package(ArgT0&& arg0, ArgT... args);
  std::string* mutable_ruby_package();
  PROTOBUF_NODISCARD std::string* release_ruby_package();
  void set_allocated_ruby_package(std::string* ruby_package);
  private:
  const std::string& _internal_ruby_package() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_ruby_package(const std::string& value);
  std::string* _internal_mutable_ruby_package();
  public:

  // optional bool java_multiple_files = 10 [default = false];
  bool has_java_multiple_files() const;
  private:
  bool _internal_has_java_multiple_files() const;
  public:
  void clear_java_multiple_files();
  bool java_multiple_files() const;
  void set_java_multiple_files(bool value);
  private:
  bool _internal_java_multiple_files() const;
  void _internal_set_java_multiple_files(bool value);
  public:

  // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
  PROTOBUF_DEPRECATED bool has_java_generate_equals_and_hash() const;
  private:
  bool _internal_has_java_generate_equals_and_hash() const;
  public:
  PROTOBUF_DEPRECATED void clear_java_generate_equals_and_hash();
  PROTOBUF_DEPRECATED bool java_generate_equals_and_hash() const;
  PROTOBUF_DEPRECATED void set_java_generate_equals_and_hash(bool value);
  private:
  bool _internal_java_generate_equals_and_hash() const;
  void _internal_set_java_generate_equals_and_hash(bool value);
  public:

  // optional bool java_string_check_utf8 = 27 [default = false];
  bool has_java_string_check_utf8() const;
  private:
  bool _internal_has_java_string_check_utf8() const;
  public:
  void clear_java_string_check_utf8();
  bool java_string_check_utf8() const;
  void set_java_string_check_utf8(bool value);
  private:
  bool _internal_java_string_check_utf8() const;
  void _internal_set_java_string_check_utf8(bool value);
  public:

  // optional bool cc_generic_services = 16 [default = false];
  bool has_cc_generic_services() const;
  private:
  bool _internal_has_cc_generic_services() const;
  public:
  void clear_cc_generic_services();
  bool cc_generic_services() const;
  void set_cc_generic_services(bool value);
  private:
  bool _internal_cc_generic_services() const;
  void _internal_set_cc_generic_services(bool value);
  public:

  // optional bool java_generic_services = 17 [default = false];
  bool has_java_generic_services() const;
  private:
  bool _internal_has_java_generic_services() const;
  public:
  void clear_java_generic_services();
  bool java_generic_services() const;
  void set_java_generic_services(bool value);
  private:
  bool _internal_java_generic_services() const;
  void _internal_set_java_generic_services(bool value);
  public:

  // optional bool py_generic_services = 18 [default = false];
  bool has_py_generic_services() const;
  private:
  bool _internal_has_py_generic_services() const;
  public:
  void clear_py_generic_services();
  bool py_generic_services() const;
  void set_py_generic_services(bool value);
  private:
  bool _internal_py_generic_services() const;
  void _internal_set_py_generic_services(bool value);
  public:

  // optional bool php_generic_services = 42 [default = false];
  bool has_php_generic_services() const;
  private:
  bool _internal_has_php_generic_services() const;
  public:
  void clear_php_generic_services();
  bool php_generic_services() const;
  void set_php_generic_services(bool value);
  private:
  bool _internal_php_generic_services() const;
  void _internal_set_php_generic_services(bool value);
  public:

  // optional bool deprecated = 23 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  bool has_optimize_for() const;
  private:
  bool _internal_has_optimize_for() const;
  public:
  void clear_optimize_for();
  ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode optimize_for() const;
  void set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value);
  private:
  ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode _internal_optimize_for() const;
  void _internal_set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value);
  public:

  // optional bool cc_enable_arenas = 31 [default = true];
  bool has_cc_enable_arenas() const;
  private:
  bool _internal_has_cc_enable_arenas() const;
  public:
  void clear_cc_enable_arenas();
  bool cc_enable_arenas() const;
  void set_cc_enable_arenas(bool value);
  private:
  bool _internal_cc_enable_arenas() const;
  void _internal_set_cc_enable_arenas(bool value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FileOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr java_package_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr java_outer_classname_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr go_package_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr objc_class_prefix_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr csharp_namespace_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr swift_prefix_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_class_prefix_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_namespace_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr php_metadata_namespace_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ruby_package_;
    bool java_multiple_files_;
    bool java_generate_equals_and_hash_;
    bool java_string_check_utf8_;
    bool cc_generic_services_;
    bool java_generic_services_;
    bool py_generic_services_;
    bool php_generic_services_;
    bool deprecated_;
    int optimize_for_;
    bool cc_enable_arenas_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT MessageOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ {
 public:
  inline MessageOptions() : MessageOptions(nullptr) {}
  ~MessageOptions() override;
  explicit PROTOBUF_CONSTEXPR MessageOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  MessageOptions(const MessageOptions& from);
  MessageOptions(MessageOptions&& from) noexcept
    : MessageOptions() {
    *this = ::std::move(from);
  }

  inline MessageOptions& operator=(const MessageOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline MessageOptions& operator=(MessageOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const MessageOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const MessageOptions* internal_default_instance() {
    return reinterpret_cast<const MessageOptions*>(
               &_MessageOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    14;

  friend void swap(MessageOptions& a, MessageOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(MessageOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MessageOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  MessageOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<MessageOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const MessageOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const MessageOptions& from) {
    MessageOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MessageOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.MessageOptions";
  }
  protected:
  explicit MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kMessageSetWireFormatFieldNumber = 1,
    kNoStandardDescriptorAccessorFieldNumber = 2,
    kDeprecatedFieldNumber = 3,
    kMapEntryFieldNumber = 7,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional bool message_set_wire_format = 1 [default = false];
  bool has_message_set_wire_format() const;
  private:
  bool _internal_has_message_set_wire_format() const;
  public:
  void clear_message_set_wire_format();
  bool message_set_wire_format() const;
  void set_message_set_wire_format(bool value);
  private:
  bool _internal_message_set_wire_format() const;
  void _internal_set_message_set_wire_format(bool value);
  public:

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  bool has_no_standard_descriptor_accessor() const;
  private:
  bool _internal_has_no_standard_descriptor_accessor() const;
  public:
  void clear_no_standard_descriptor_accessor();
  bool no_standard_descriptor_accessor() const;
  void set_no_standard_descriptor_accessor(bool value);
  private:
  bool _internal_no_standard_descriptor_accessor() const;
  void _internal_set_no_standard_descriptor_accessor(bool value);
  public:

  // optional bool deprecated = 3 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:

  // optional bool map_entry = 7;
  bool has_map_entry() const;
  private:
  bool _internal_has_map_entry() const;
  public:
  void clear_map_entry();
  bool map_entry() const;
  void set_map_entry(bool value);
  private:
  bool _internal_map_entry() const;
  void _internal_set_map_entry(bool value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MessageOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    bool message_set_wire_format_;
    bool no_standard_descriptor_accessor_;
    bool deprecated_;
    bool map_entry_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FieldOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ {
 public:
  inline FieldOptions() : FieldOptions(nullptr) {}
  ~FieldOptions() override;
  explicit PROTOBUF_CONSTEXPR FieldOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  FieldOptions(const FieldOptions& from);
  FieldOptions(FieldOptions&& from) noexcept
    : FieldOptions() {
    *this = ::std::move(from);
  }

  inline FieldOptions& operator=(const FieldOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline FieldOptions& operator=(FieldOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FieldOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const FieldOptions* internal_default_instance() {
    return reinterpret_cast<const FieldOptions*>(
               &_FieldOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    15;

  friend void swap(FieldOptions& a, FieldOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(FieldOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FieldOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  FieldOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<FieldOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const FieldOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const FieldOptions& from) {
    FieldOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(FieldOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.FieldOptions";
  }
  protected:
  explicit FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef FieldOptions_CType CType;
  static constexpr CType STRING =
    FieldOptions_CType_STRING;
  static constexpr CType CORD =
    FieldOptions_CType_CORD;
  static constexpr CType STRING_PIECE =
    FieldOptions_CType_STRING_PIECE;
  static inline bool CType_IsValid(int value) {
    return FieldOptions_CType_IsValid(value);
  }
  static constexpr CType CType_MIN =
    FieldOptions_CType_CType_MIN;
  static constexpr CType CType_MAX =
    FieldOptions_CType_CType_MAX;
  static constexpr int CType_ARRAYSIZE =
    FieldOptions_CType_CType_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  CType_descriptor() {
    return FieldOptions_CType_descriptor();
  }
  template<typename T>
  static inline const std::string& CType_Name(T enum_t_value) {
    static_assert(::std::is_same<T, CType>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function CType_Name.");
    return FieldOptions_CType_Name(enum_t_value);
  }
  static inline bool CType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      CType* value) {
    return FieldOptions_CType_Parse(name, value);
  }

  typedef FieldOptions_JSType JSType;
  static constexpr JSType JS_NORMAL =
    FieldOptions_JSType_JS_NORMAL;
  static constexpr JSType JS_STRING =
    FieldOptions_JSType_JS_STRING;
  static constexpr JSType JS_NUMBER =
    FieldOptions_JSType_JS_NUMBER;
  static inline bool JSType_IsValid(int value) {
    return FieldOptions_JSType_IsValid(value);
  }
  static constexpr JSType JSType_MIN =
    FieldOptions_JSType_JSType_MIN;
  static constexpr JSType JSType_MAX =
    FieldOptions_JSType_JSType_MAX;
  static constexpr int JSType_ARRAYSIZE =
    FieldOptions_JSType_JSType_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  JSType_descriptor() {
    return FieldOptions_JSType_descriptor();
  }
  template<typename T>
  static inline const std::string& JSType_Name(T enum_t_value) {
    static_assert(::std::is_same<T, JSType>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function JSType_Name.");
    return FieldOptions_JSType_Name(enum_t_value);
  }
  static inline bool JSType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      JSType* value) {
    return FieldOptions_JSType_Parse(name, value);
  }

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kCtypeFieldNumber = 1,
    kJstypeFieldNumber = 6,
    kPackedFieldNumber = 2,
    kLazyFieldNumber = 5,
    kUnverifiedLazyFieldNumber = 15,
    kDeprecatedFieldNumber = 3,
    kWeakFieldNumber = 10,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  bool has_ctype() const;
  private:
  bool _internal_has_ctype() const;
  public:
  void clear_ctype();
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType ctype() const;
  void set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value);
  private:
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType _internal_ctype() const;
  void _internal_set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value);
  public:

  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
  bool has_jstype() const;
  private:
  bool _internal_has_jstype() const;
  public:
  void clear_jstype();
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType jstype() const;
  void set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value);
  private:
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType _internal_jstype() const;
  void _internal_set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value);
  public:

  // optional bool packed = 2;
  bool has_packed() const;
  private:
  bool _internal_has_packed() const;
  public:
  void clear_packed();
  bool packed() const;
  void set_packed(bool value);
  private:
  bool _internal_packed() const;
  void _internal_set_packed(bool value);
  public:

  // optional bool lazy = 5 [default = false];
  bool has_lazy() const;
  private:
  bool _internal_has_lazy() const;
  public:
  void clear_lazy();
  bool lazy() const;
  void set_lazy(bool value);
  private:
  bool _internal_lazy() const;
  void _internal_set_lazy(bool value);
  public:

  // optional bool unverified_lazy = 15 [default = false];
  bool has_unverified_lazy() const;
  private:
  bool _internal_has_unverified_lazy() const;
  public:
  void clear_unverified_lazy();
  bool unverified_lazy() const;
  void set_unverified_lazy(bool value);
  private:
  bool _internal_unverified_lazy() const;
  void _internal_set_unverified_lazy(bool value);
  public:

  // optional bool deprecated = 3 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:

  // optional bool weak = 10 [default = false];
  bool has_weak() const;
  private:
  bool _internal_has_weak() const;
  public:
  void clear_weak();
  bool weak() const;
  void set_weak(bool value);
  private:
  bool _internal_weak() const;
  void _internal_set_weak(bool value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          FieldOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    int ctype_;
    int jstype_;
    bool packed_;
    bool lazy_;
    bool unverified_lazy_;
    bool deprecated_;
    bool weak_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT OneofOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ {
 public:
  inline OneofOptions() : OneofOptions(nullptr) {}
  ~OneofOptions() override;
  explicit PROTOBUF_CONSTEXPR OneofOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  OneofOptions(const OneofOptions& from);
  OneofOptions(OneofOptions&& from) noexcept
    : OneofOptions() {
    *this = ::std::move(from);
  }

  inline OneofOptions& operator=(const OneofOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline OneofOptions& operator=(OneofOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const OneofOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const OneofOptions* internal_default_instance() {
    return reinterpret_cast<const OneofOptions*>(
               &_OneofOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    16;

  friend void swap(OneofOptions& a, OneofOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(OneofOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(OneofOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  OneofOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<OneofOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const OneofOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const OneofOptions& from) {
    OneofOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(OneofOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.OneofOptions";
  }
  protected:
  explicit OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          OneofOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ {
 public:
  inline EnumOptions() : EnumOptions(nullptr) {}
  ~EnumOptions() override;
  explicit PROTOBUF_CONSTEXPR EnumOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  EnumOptions(const EnumOptions& from);
  EnumOptions(EnumOptions&& from) noexcept
    : EnumOptions() {
    *this = ::std::move(from);
  }

  inline EnumOptions& operator=(const EnumOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline EnumOptions& operator=(EnumOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const EnumOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const EnumOptions* internal_default_instance() {
    return reinterpret_cast<const EnumOptions*>(
               &_EnumOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    17;

  friend void swap(EnumOptions& a, EnumOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(EnumOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  EnumOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<EnumOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const EnumOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const EnumOptions& from) {
    EnumOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.EnumOptions";
  }
  protected:
  explicit EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kAllowAliasFieldNumber = 2,
    kDeprecatedFieldNumber = 3,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional bool allow_alias = 2;
  bool has_allow_alias() const;
  private:
  bool _internal_has_allow_alias() const;
  public:
  void clear_allow_alias();
  bool allow_alias() const;
  void set_allow_alias(bool value);
  private:
  bool _internal_allow_alias() const;
  void _internal_set_allow_alias(bool value);
  public:

  // optional bool deprecated = 3 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    bool allow_alias_;
    bool deprecated_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumValueOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ {
 public:
  inline EnumValueOptions() : EnumValueOptions(nullptr) {}
  ~EnumValueOptions() override;
  explicit PROTOBUF_CONSTEXPR EnumValueOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  EnumValueOptions(const EnumValueOptions& from);
  EnumValueOptions(EnumValueOptions&& from) noexcept
    : EnumValueOptions() {
    *this = ::std::move(from);
  }

  inline EnumValueOptions& operator=(const EnumValueOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const EnumValueOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const EnumValueOptions* internal_default_instance() {
    return reinterpret_cast<const EnumValueOptions*>(
               &_EnumValueOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    18;

  friend void swap(EnumValueOptions& a, EnumValueOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(EnumValueOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumValueOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  EnumValueOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<EnumValueOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const EnumValueOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const EnumValueOptions& from) {
    EnumValueOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EnumValueOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.EnumValueOptions";
  }
  protected:
  explicit EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kDeprecatedFieldNumber = 1,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional bool deprecated = 1 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          EnumValueOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    bool deprecated_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ServiceOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ {
 public:
  inline ServiceOptions() : ServiceOptions(nullptr) {}
  ~ServiceOptions() override;
  explicit PROTOBUF_CONSTEXPR ServiceOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ServiceOptions(const ServiceOptions& from);
  ServiceOptions(ServiceOptions&& from) noexcept
    : ServiceOptions() {
    *this = ::std::move(from);
  }

  inline ServiceOptions& operator=(const ServiceOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline ServiceOptions& operator=(ServiceOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ServiceOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const ServiceOptions* internal_default_instance() {
    return reinterpret_cast<const ServiceOptions*>(
               &_ServiceOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    19;

  friend void swap(ServiceOptions& a, ServiceOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(ServiceOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ServiceOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  ServiceOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<ServiceOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const ServiceOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const ServiceOptions& from) {
    ServiceOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ServiceOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.ServiceOptions";
  }
  protected:
  explicit ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kDeprecatedFieldNumber = 33,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional bool deprecated = 33 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          ServiceOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    bool deprecated_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT MethodOptions final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ {
 public:
  inline MethodOptions() : MethodOptions(nullptr) {}
  ~MethodOptions() override;
  explicit PROTOBUF_CONSTEXPR MethodOptions(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  MethodOptions(const MethodOptions& from);
  MethodOptions(MethodOptions&& from) noexcept
    : MethodOptions() {
    *this = ::std::move(from);
  }

  inline MethodOptions& operator=(const MethodOptions& from) {
    CopyFrom(from);
    return *this;
  }
  inline MethodOptions& operator=(MethodOptions&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const MethodOptions& default_instance() {
    return *internal_default_instance();
  }
  static inline const MethodOptions* internal_default_instance() {
    return reinterpret_cast<const MethodOptions*>(
               &_MethodOptions_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    20;

  friend void swap(MethodOptions& a, MethodOptions& b) {
    a.Swap(&b);
  }
  inline void Swap(MethodOptions* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MethodOptions* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  MethodOptions* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<MethodOptions>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const MethodOptions& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const MethodOptions& from) {
    MethodOptions::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MethodOptions* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.MethodOptions";
  }
  protected:
  explicit MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef MethodOptions_IdempotencyLevel IdempotencyLevel;
  static constexpr IdempotencyLevel IDEMPOTENCY_UNKNOWN =
    MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN;
  static constexpr IdempotencyLevel NO_SIDE_EFFECTS =
    MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS;
  static constexpr IdempotencyLevel IDEMPOTENT =
    MethodOptions_IdempotencyLevel_IDEMPOTENT;
  static inline bool IdempotencyLevel_IsValid(int value) {
    return MethodOptions_IdempotencyLevel_IsValid(value);
  }
  static constexpr IdempotencyLevel IdempotencyLevel_MIN =
    MethodOptions_IdempotencyLevel_IdempotencyLevel_MIN;
  static constexpr IdempotencyLevel IdempotencyLevel_MAX =
    MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX;
  static constexpr int IdempotencyLevel_ARRAYSIZE =
    MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  IdempotencyLevel_descriptor() {
    return MethodOptions_IdempotencyLevel_descriptor();
  }
  template<typename T>
  static inline const std::string& IdempotencyLevel_Name(T enum_t_value) {
    static_assert(::std::is_same<T, IdempotencyLevel>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function IdempotencyLevel_Name.");
    return MethodOptions_IdempotencyLevel_Name(enum_t_value);
  }
  static inline bool IdempotencyLevel_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      IdempotencyLevel* value) {
    return MethodOptions_IdempotencyLevel_Parse(name, value);
  }

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kDeprecatedFieldNumber = 33,
    kIdempotencyLevelFieldNumber = 34,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;
  public:
  void clear_uninterpreted_option();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >*
      mutable_uninterpreted_option();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& _internal_uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* _internal_add_uninterpreted_option();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption& uninterpreted_option(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption* add_uninterpreted_option();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >&
      uninterpreted_option() const;

  // optional bool deprecated = 33 [default = false];
  bool has_deprecated() const;
  private:
  bool _internal_has_deprecated() const;
  public:
  void clear_deprecated();
  bool deprecated() const;
  void set_deprecated(bool value);
  private:
  bool _internal_deprecated() const;
  void _internal_set_deprecated(bool value);
  public:

  // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
  bool has_idempotency_level() const;
  private:
  bool _internal_has_idempotency_level() const;
  public:
  void clear_idempotency_level();
  ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel idempotency_level() const;
  void set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value);
  private:
  ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel _internal_idempotency_level() const;
  void _internal_set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value);
  public:


  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline bool HasExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.Has(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void ClearExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    _impl_._extensions_.ClearExtension(id.number());

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline int ExtensionSize(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_,
                                  id.default_value());
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Mutable(id.number(), _field_type,
                                      &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::ConstType value) {
    _proto_TypeTraits::Set(id.number(), _field_type, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,
                                    &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Singular::MutableType value) {
    _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,
                                               value, &_impl_._extensions_);

  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
              MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::Release(id.number(), _field_type,
                                      &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) const {

    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index) {

    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      int index, typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Set(id.number(), index, value, &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);

    return to_add;
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id,
      typename _proto_TypeTraits::Repeated::ConstType value) {
    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,
                           &_impl_._extensions_);

  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) const {

    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits,
            ::PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<
          MethodOptions, _proto_TypeTraits, _field_type, _is_packed>& id) {

    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }

  // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_;

    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_;
    bool deprecated_;
    int idempotency_level_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT UninterpretedOption_NamePart final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ {
 public:
  inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {}
  ~UninterpretedOption_NamePart() override;
  explicit PROTOBUF_CONSTEXPR UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
  UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept
    : UninterpretedOption_NamePart() {
    *this = ::std::move(from);
  }

  inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) {
    CopyFrom(from);
    return *this;
  }
  inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const UninterpretedOption_NamePart& default_instance() {
    return *internal_default_instance();
  }
  static inline const UninterpretedOption_NamePart* internal_default_instance() {
    return reinterpret_cast<const UninterpretedOption_NamePart*>(
               &_UninterpretedOption_NamePart_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    21;

  friend void swap(UninterpretedOption_NamePart& a, UninterpretedOption_NamePart& b) {
    a.Swap(&b);
  }
  inline void Swap(UninterpretedOption_NamePart* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(UninterpretedOption_NamePart* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  UninterpretedOption_NamePart* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<UninterpretedOption_NamePart>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const UninterpretedOption_NamePart& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const UninterpretedOption_NamePart& from) {
    UninterpretedOption_NamePart::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(UninterpretedOption_NamePart* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.UninterpretedOption.NamePart";
  }
  protected:
  explicit UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kNamePartFieldNumber = 1,
    kIsExtensionFieldNumber = 2,
  };
  // required string name_part = 1;
  bool has_name_part() const;
  private:
  bool _internal_has_name_part() const;
  public:
  void clear_name_part();
  const std::string& name_part() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name_part(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name_part();
  PROTOBUF_NODISCARD std::string* release_name_part();
  void set_allocated_name_part(std::string* name_part);
  private:
  const std::string& _internal_name_part() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name_part(const std::string& value);
  std::string* _internal_mutable_name_part();
  public:

  // required bool is_extension = 2;
  bool has_is_extension() const;
  private:
  bool _internal_has_is_extension() const;
  public:
  void clear_is_extension();
  bool is_extension() const;
  void set_is_extension(bool value);
  private:
  bool _internal_is_extension() const;
  void _internal_set_is_extension(bool value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
 private:
  class _Internal;

  // helper for ByteSizeLong()
  size_t RequiredFieldsByteSizeFallback() const;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_part_;
    bool is_extension_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT UninterpretedOption final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ {
 public:
  inline UninterpretedOption() : UninterpretedOption(nullptr) {}
  ~UninterpretedOption() override;
  explicit PROTOBUF_CONSTEXPR UninterpretedOption(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  UninterpretedOption(const UninterpretedOption& from);
  UninterpretedOption(UninterpretedOption&& from) noexcept
    : UninterpretedOption() {
    *this = ::std::move(from);
  }

  inline UninterpretedOption& operator=(const UninterpretedOption& from) {
    CopyFrom(from);
    return *this;
  }
  inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const UninterpretedOption& default_instance() {
    return *internal_default_instance();
  }
  static inline const UninterpretedOption* internal_default_instance() {
    return reinterpret_cast<const UninterpretedOption*>(
               &_UninterpretedOption_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    22;

  friend void swap(UninterpretedOption& a, UninterpretedOption& b) {
    a.Swap(&b);
  }
  inline void Swap(UninterpretedOption* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(UninterpretedOption* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  UninterpretedOption* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<UninterpretedOption>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const UninterpretedOption& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const UninterpretedOption& from) {
    UninterpretedOption::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(UninterpretedOption* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.UninterpretedOption";
  }
  protected:
  explicit UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef UninterpretedOption_NamePart NamePart;

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

  enum : int {
    kNameFieldNumber = 2,
    kIdentifierValueFieldNumber = 3,
    kStringValueFieldNumber = 7,
    kAggregateValueFieldNumber = 8,
    kPositiveIntValueFieldNumber = 4,
    kNegativeIntValueFieldNumber = 5,
    kDoubleValueFieldNumber = 6,
  };
  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  int name_size() const;
  private:
  int _internal_name_size() const;
  public:
  void clear_name();
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* mutable_name(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >*
      mutable_name();
  private:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& _internal_name(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* _internal_add_name();
  public:
  const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& name(int index) const;
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* add_name();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >&
      name() const;

  // optional string identifier_value = 3;
  bool has_identifier_value() const;
  private:
  bool _internal_has_identifier_value() const;
  public:
  void clear_identifier_value();
  const std::string& identifier_value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_identifier_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_identifier_value();
  PROTOBUF_NODISCARD std::string* release_identifier_value();
  void set_allocated_identifier_value(std::string* identifier_value);
  private:
  const std::string& _internal_identifier_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_identifier_value(const std::string& value);
  std::string* _internal_mutable_identifier_value();
  public:

  // optional bytes string_value = 7;
  bool has_string_value() const;
  private:
  bool _internal_has_string_value() const;
  public:
  void clear_string_value();
  const std::string& string_value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_string_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_string_value();
  PROTOBUF_NODISCARD std::string* release_string_value();
  void set_allocated_string_value(std::string* string_value);
  private:
  const std::string& _internal_string_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(const std::string& value);
  std::string* _internal_mutable_string_value();
  public:

  // optional string aggregate_value = 8;
  bool has_aggregate_value() const;
  private:
  bool _internal_has_aggregate_value() const;
  public:
  void clear_aggregate_value();
  const std::string& aggregate_value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_aggregate_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_aggregate_value();
  PROTOBUF_NODISCARD std::string* release_aggregate_value();
  void set_allocated_aggregate_value(std::string* aggregate_value);
  private:
  const std::string& _internal_aggregate_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_aggregate_value(const std::string& value);
  std::string* _internal_mutable_aggregate_value();
  public:

  // optional uint64 positive_int_value = 4;
  bool has_positive_int_value() const;
  private:
  bool _internal_has_positive_int_value() const;
  public:
  void clear_positive_int_value();
  uint64_t positive_int_value() const;
  void set_positive_int_value(uint64_t value);
  private:
  uint64_t _internal_positive_int_value() const;
  void _internal_set_positive_int_value(uint64_t value);
  public:

  // optional int64 negative_int_value = 5;
  bool has_negative_int_value() const;
  private:
  bool _internal_has_negative_int_value() const;
  public:
  void clear_negative_int_value();
  int64_t negative_int_value() const;
  void set_negative_int_value(int64_t value);
  private:
  int64_t _internal_negative_int_value() const;
  void _internal_set_negative_int_value(int64_t value);
  public:

  // optional double double_value = 6;
  bool has_double_value() const;
  private:
  bool _internal_has_double_value() const;
  public:
  void clear_double_value();
  double double_value() const;
  void set_double_value(double value);
  private:
  double _internal_double_value() const;
  void _internal_set_double_value(double value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart > name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr identifier_value_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr aggregate_value_;
    uint64_t positive_int_value_;
    int64_t negative_int_value_;
    double double_value_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT SourceCodeInfo_Location final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ {
 public:
  inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {}
  ~SourceCodeInfo_Location() override;
  explicit PROTOBUF_CONSTEXPR SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
  SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept
    : SourceCodeInfo_Location() {
    *this = ::std::move(from);
  }

  inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
    CopyFrom(from);
    return *this;
  }
  inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const SourceCodeInfo_Location& default_instance() {
    return *internal_default_instance();
  }
  static inline const SourceCodeInfo_Location* internal_default_instance() {
    return reinterpret_cast<const SourceCodeInfo_Location*>(
               &_SourceCodeInfo_Location_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    23;

  friend void swap(SourceCodeInfo_Location& a, SourceCodeInfo_Location& b) {
    a.Swap(&b);
  }
  inline void Swap(SourceCodeInfo_Location* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(SourceCodeInfo_Location* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  SourceCodeInfo_Location* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<SourceCodeInfo_Location>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const SourceCodeInfo_Location& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const SourceCodeInfo_Location& from) {
    SourceCodeInfo_Location::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(SourceCodeInfo_Location* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.SourceCodeInfo.Location";
  }
  protected:
  explicit SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kPathFieldNumber = 1,
    kSpanFieldNumber = 2,
    kLeadingDetachedCommentsFieldNumber = 6,
    kLeadingCommentsFieldNumber = 3,
    kTrailingCommentsFieldNumber = 4,
  };
  // repeated int32 path = 1 [packed = true];
  int path_size() const;
  private:
  int _internal_path_size() const;
  public:
  void clear_path();
  private:
  int32_t _internal_path(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      _internal_path() const;
  void _internal_add_path(int32_t value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      _internal_mutable_path();
  public:
  int32_t path(int index) const;
  void set_path(int index, int32_t value);
  void add_path(int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      path() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      mutable_path();

  // repeated int32 span = 2 [packed = true];
  int span_size() const;
  private:
  int _internal_span_size() const;
  public:
  void clear_span();
  private:
  int32_t _internal_span(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      _internal_span() const;
  void _internal_add_span(int32_t value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      _internal_mutable_span();
  public:
  int32_t span(int index) const;
  void set_span(int index, int32_t value);
  void add_span(int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      span() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      mutable_span();

  // repeated string leading_detached_comments = 6;
  int leading_detached_comments_size() const;
  private:
  int _internal_leading_detached_comments_size() const;
  public:
  void clear_leading_detached_comments();
  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, 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(std::string&& value);
  void add_leading_detached_comments(const char* value);
  void add_leading_detached_comments(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& leading_detached_comments() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_leading_detached_comments();
  private:
  const std::string& _internal_leading_detached_comments(int index) const;
  std::string* _internal_add_leading_detached_comments();
  public:

  // optional string leading_comments = 3;
  bool has_leading_comments() const;
  private:
  bool _internal_has_leading_comments() const;
  public:
  void clear_leading_comments();
  const std::string& leading_comments() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_leading_comments(ArgT0&& arg0, ArgT... args);
  std::string* mutable_leading_comments();
  PROTOBUF_NODISCARD std::string* release_leading_comments();
  void set_allocated_leading_comments(std::string* leading_comments);
  private:
  const std::string& _internal_leading_comments() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_leading_comments(const std::string& value);
  std::string* _internal_mutable_leading_comments();
  public:

  // optional string trailing_comments = 4;
  bool has_trailing_comments() const;
  private:
  bool _internal_has_trailing_comments() const;
  public:
  void clear_trailing_comments();
  const std::string& trailing_comments() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_trailing_comments(ArgT0&& arg0, ArgT... args);
  std::string* mutable_trailing_comments();
  PROTOBUF_NODISCARD std::string* release_trailing_comments();
  void set_allocated_trailing_comments(std::string* trailing_comments);
  private:
  const std::string& _internal_trailing_comments() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_trailing_comments(const std::string& value);
  std::string* _internal_mutable_trailing_comments();
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > path_;
    mutable std::atomic<int> _path_cached_byte_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > span_;
    mutable std::atomic<int> _span_cached_byte_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> leading_detached_comments_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr leading_comments_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr trailing_comments_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT SourceCodeInfo final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ {
 public:
  inline SourceCodeInfo() : SourceCodeInfo(nullptr) {}
  ~SourceCodeInfo() override;
  explicit PROTOBUF_CONSTEXPR SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  SourceCodeInfo(const SourceCodeInfo& from);
  SourceCodeInfo(SourceCodeInfo&& from) noexcept
    : SourceCodeInfo() {
    *this = ::std::move(from);
  }

  inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
    CopyFrom(from);
    return *this;
  }
  inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const SourceCodeInfo& default_instance() {
    return *internal_default_instance();
  }
  static inline const SourceCodeInfo* internal_default_instance() {
    return reinterpret_cast<const SourceCodeInfo*>(
               &_SourceCodeInfo_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    24;

  friend void swap(SourceCodeInfo& a, SourceCodeInfo& b) {
    a.Swap(&b);
  }
  inline void Swap(SourceCodeInfo* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(SourceCodeInfo* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  SourceCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<SourceCodeInfo>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const SourceCodeInfo& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const SourceCodeInfo& from) {
    SourceCodeInfo::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(SourceCodeInfo* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.SourceCodeInfo";
  }
  protected:
  explicit SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef SourceCodeInfo_Location Location;

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

  enum : int {
    kLocationFieldNumber = 1,
  };
  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  int location_size() const;
  private:
  int _internal_location_size() const;
  public:
  void clear_location();
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* mutable_location(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >*
      mutable_location();
  private:
  const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& _internal_location(int index) const;
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* _internal_add_location();
  public:
  const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location& location(int index) const;
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location* add_location();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >&
      location() const;

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

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location > location_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ {
 public:
  inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {}
  ~GeneratedCodeInfo_Annotation() override;
  explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from);
  GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept
    : GeneratedCodeInfo_Annotation() {
    *this = ::std::move(from);
  }

  inline GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) {
    CopyFrom(from);
    return *this;
  }
  inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GeneratedCodeInfo_Annotation& default_instance() {
    return *internal_default_instance();
  }
  static inline const GeneratedCodeInfo_Annotation* internal_default_instance() {
    return reinterpret_cast<const GeneratedCodeInfo_Annotation*>(
               &_GeneratedCodeInfo_Annotation_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    25;

  friend void swap(GeneratedCodeInfo_Annotation& a, GeneratedCodeInfo_Annotation& b) {
    a.Swap(&b);
  }
  inline void Swap(GeneratedCodeInfo_Annotation* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GeneratedCodeInfo_Annotation* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  GeneratedCodeInfo_Annotation* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<GeneratedCodeInfo_Annotation>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const GeneratedCodeInfo_Annotation& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const GeneratedCodeInfo_Annotation& from) {
    GeneratedCodeInfo_Annotation::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GeneratedCodeInfo_Annotation* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.GeneratedCodeInfo.Annotation";
  }
  protected:
  explicit GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

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

  enum : int {
    kPathFieldNumber = 1,
    kSourceFileFieldNumber = 2,
    kBeginFieldNumber = 3,
    kEndFieldNumber = 4,
  };
  // repeated int32 path = 1 [packed = true];
  int path_size() const;
  private:
  int _internal_path_size() const;
  public:
  void clear_path();
  private:
  int32_t _internal_path(int index) const;
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      _internal_path() const;
  void _internal_add_path(int32_t value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      _internal_mutable_path();
  public:
  int32_t path(int index) const;
  void set_path(int index, int32_t value);
  void add_path(int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >&
      path() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t >*
      mutable_path();

  // optional string source_file = 2;
  bool has_source_file() const;
  private:
  bool _internal_has_source_file() const;
  public:
  void clear_source_file();
  const std::string& source_file() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_source_file(ArgT0&& arg0, ArgT... args);
  std::string* mutable_source_file();
  PROTOBUF_NODISCARD std::string* release_source_file();
  void set_allocated_source_file(std::string* source_file);
  private:
  const std::string& _internal_source_file() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_source_file(const std::string& value);
  std::string* _internal_mutable_source_file();
  public:

  // optional int32 begin = 3;
  bool has_begin() const;
  private:
  bool _internal_has_begin() const;
  public:
  void clear_begin();
  int32_t begin() const;
  void set_begin(int32_t value);
  private:
  int32_t _internal_begin() const;
  void _internal_set_begin(int32_t value);
  public:

  // optional int32 end = 4;
  bool has_end() const;
  private:
  bool _internal_has_end() const;
  public:
  void clear_end();
  int32_t end() const;
  void set_end(int32_t value);
  private:
  int32_t _internal_end() const;
  void _internal_set_end(int32_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedField< int32_t > path_;
    mutable std::atomic<int> _path_cached_byte_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr source_file_;
    int32_t begin_;
    int32_t end_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT GeneratedCodeInfo final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ {
 public:
  inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {}
  ~GeneratedCodeInfo() override;
  explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GeneratedCodeInfo(const GeneratedCodeInfo& from);
  GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept
    : GeneratedCodeInfo() {
    *this = ::std::move(from);
  }

  inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) {
    CopyFrom(from);
    return *this;
  }
  inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GeneratedCodeInfo& default_instance() {
    return *internal_default_instance();
  }
  static inline const GeneratedCodeInfo* internal_default_instance() {
    return reinterpret_cast<const GeneratedCodeInfo*>(
               &_GeneratedCodeInfo_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    26;

  friend void swap(GeneratedCodeInfo& a, GeneratedCodeInfo& b) {
    a.Swap(&b);
  }
  inline void Swap(GeneratedCodeInfo* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GeneratedCodeInfo* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  GeneratedCodeInfo* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<GeneratedCodeInfo>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const GeneratedCodeInfo& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const GeneratedCodeInfo& from) {
    GeneratedCodeInfo::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GeneratedCodeInfo* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.GeneratedCodeInfo";
  }
  protected:
  explicit GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

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

  typedef GeneratedCodeInfo_Annotation Annotation;

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

  enum : int {
    kAnnotationFieldNumber = 1,
  };
  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  int annotation_size() const;
  private:
  int _internal_annotation_size() const;
  public:
  void clear_annotation();
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* mutable_annotation(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >*
      mutable_annotation();
  private:
  const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& _internal_annotation(int index) const;
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* _internal_add_annotation();
  public:
  const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation& annotation(int index) const;
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation* add_annotation();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >&
      annotation() const;

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

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation > annotation_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// ===================================================================


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

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// FileDescriptorSet

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

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

// FileDescriptorProto

// optional string name = 1;
inline bool FileDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool FileDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void FileDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FileDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
}
inline std::string* FileDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
  return _s;
}
inline const std::string& FileDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void FileDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
}

// optional string package = 2;
inline bool FileDescriptorProto::_internal_has_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool FileDescriptorProto::has_package() const {
  return _internal_has_package();
}
inline void FileDescriptorProto::clear_package() {
  _impl_.package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& FileDescriptorProto::package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
  return _internal_package();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileDescriptorProto::set_package(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
}
inline std::string* FileDescriptorProto::mutable_package() {
  std::string* _s = _internal_mutable_package();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
  return _s;
}
inline const std::string& FileDescriptorProto::_internal_package() const {
  return _impl_.package_.Get();
}
inline void FileDescriptorProto::_internal_set_package(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.package_.Set(value, GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::_internal_mutable_package() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.package_.Mutable(GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::release_package() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package)
  if (!_internal_has_package()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.package_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.package_.IsDefault()) {
    _impl_.package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileDescriptorProto::set_allocated_package(std::string* package) {
  if (package != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.package_.SetAllocated(package, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.package_.IsDefault()) {
    _impl_.package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
}

// repeated string dependency = 3;
inline int FileDescriptorProto::_internal_dependency_size() const {
  return _impl_.dependency_.size();
}
inline int FileDescriptorProto::dependency_size() const {
  return _internal_dependency_size();
}
inline void FileDescriptorProto::clear_dependency() {
  _impl_.dependency_.Clear();
}
inline std::string* FileDescriptorProto::add_dependency() {
  std::string* _s = _internal_add_dependency();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency)
  return _s;
}
inline const std::string& FileDescriptorProto::_internal_dependency(int index) const {
  return _impl_.dependency_.Get(index);
}
inline const std::string& FileDescriptorProto::dependency(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
  return _internal_dependency(index);
}
inline std::string* FileDescriptorProto::mutable_dependency(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
  return _impl_.dependency_.Mutable(index);
}
inline void FileDescriptorProto::set_dependency(int index, const std::string& value) {
  _impl_.dependency_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::set_dependency(int index, std::string&& value) {
  _impl_.dependency_.Mutable(index)->assign(std::move(value));
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.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) {
  _impl_.dependency_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline std::string* FileDescriptorProto::_internal_add_dependency() {
  return _impl_.dependency_.Add();
}
inline void FileDescriptorProto::add_dependency(const std::string& value) {
  _impl_.dependency_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(std::string&& value) {
  _impl_.dependency_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.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) {
  _impl_.dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
FileDescriptorProto::dependency() const {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
  return _impl_.dependency_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
FileDescriptorProto::mutable_dependency() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
  return &_impl_.dependency_;
}

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

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

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

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

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

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

// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool FileDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void FileDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::FileOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::FileOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
  return _internal_options();
}
inline void FileDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::FileOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000008u;
  ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000008u;
  ::PROTOBUF_NAMESPACE_ID::FileOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000008u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FileOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::FileOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
  return _msg;
}
inline void FileDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::FileOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
}

// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
inline bool FileDescriptorProto::_internal_has_source_code_info() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.source_code_info_ != nullptr);
  return value;
}
inline bool FileDescriptorProto::has_source_code_info() const {
  return _internal_has_source_code_info();
}
inline void FileDescriptorProto::clear_source_code_info() {
  if (_impl_.source_code_info_ != nullptr) _impl_.source_code_info_->Clear();
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const {
  const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = _impl_.source_code_info_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo&>(
      ::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
  return _internal_source_code_info();
}
inline void FileDescriptorProto::unsafe_arena_set_allocated_source_code_info(
    ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_code_info_);
  }
  _impl_.source_code_info_ = source_code_info;
  if (source_code_info) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
}
inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
  _impl_._has_bits_[0] &= ~0x00000010u;
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = _impl_.source_code_info_;
  _impl_.source_code_info_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::unsafe_arena_release_source_code_info() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info)
  _impl_._has_bits_[0] &= ~0x00000010u;
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = _impl_.source_code_info_;
  _impl_.source_code_info_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() {
  _impl_._has_bits_[0] |= 0x00000010u;
  if (_impl_.source_code_info_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceCodeInfo>(GetArenaForAllocation());
    _impl_.source_code_info_ = p;
  }
  return _impl_.source_code_info_;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
  ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* _msg = _internal_mutable_source_code_info();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
  return _msg;
}
inline void FileDescriptorProto::set_allocated_source_code_info(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.source_code_info_;
  }
  if (source_code_info) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(source_code_info);
    if (message_arena != submessage_arena) {
      source_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, source_code_info, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.source_code_info_ = source_code_info;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
}

// optional string syntax = 12;
inline bool FileDescriptorProto::_internal_has_syntax() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool FileDescriptorProto::has_syntax() const {
  return _internal_has_syntax();
}
inline void FileDescriptorProto::clear_syntax() {
  _impl_.syntax_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& FileDescriptorProto::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.syntax)
  return _internal_syntax();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileDescriptorProto::set_syntax(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000004u;
 _impl_.syntax_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
}
inline std::string* FileDescriptorProto::mutable_syntax() {
  std::string* _s = _internal_mutable_syntax();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax)
  return _s;
}
inline const std::string& FileDescriptorProto::_internal_syntax() const {
  return _impl_.syntax_.Get();
}
inline void FileDescriptorProto::_internal_set_syntax(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.syntax_.Set(value, GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::_internal_mutable_syntax() {
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.syntax_.Mutable(GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::release_syntax() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
  if (!_internal_has_syntax()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.syntax_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.syntax_.IsDefault()) {
    _impl_.syntax_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileDescriptorProto::set_allocated_syntax(std::string* syntax) {
  if (syntax != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.syntax_.SetAllocated(syntax, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.syntax_.IsDefault()) {
    _impl_.syntax_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax)
}

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

// DescriptorProto_ExtensionRange

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

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

// optional .google.protobuf.ExtensionRangeOptions options = 3;
inline bool DescriptorProto_ExtensionRange::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool DescriptorProto_ExtensionRange::has_options() const {
  return _internal_has_options();
}
inline void DescriptorProto_ExtensionRange::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options)
  return _internal_options();
}
inline void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
}
inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() {
  _impl_._has_bits_[0] &= ~0x00000001u;
  ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options)
  _impl_._has_bits_[0] &= ~0x00000001u;
  ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000001u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options)
  return _msg;
}
inline void DescriptorProto_ExtensionRange::set_allocated_options(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
}

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

// DescriptorProto_ReservedRange

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

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

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

// DescriptorProto

// optional string name = 1;
inline bool DescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool DescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void DescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& DescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void DescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
}
inline std::string* DescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
  return _s;
}
inline const std::string& DescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void DescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* DescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* DescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void DescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name)
}

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

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

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

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

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

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

// optional .google.protobuf.MessageOptions options = 7;
inline bool DescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool DescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void DescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::MessageOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::MessageOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
  return _internal_options();
}
inline void DescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::MessageOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::MessageOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000002u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MessageOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::MessageOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
  return _msg;
}
inline void DescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::MessageOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
}

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

// repeated string reserved_name = 10;
inline int DescriptorProto::_internal_reserved_name_size() const {
  return _impl_.reserved_name_.size();
}
inline int DescriptorProto::reserved_name_size() const {
  return _internal_reserved_name_size();
}
inline void DescriptorProto::clear_reserved_name() {
  _impl_.reserved_name_.Clear();
}
inline std::string* DescriptorProto::add_reserved_name() {
  std::string* _s = _internal_add_reserved_name();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name)
  return _s;
}
inline const std::string& DescriptorProto::_internal_reserved_name(int index) const {
  return _impl_.reserved_name_.Get(index);
}
inline const std::string& DescriptorProto::reserved_name(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name)
  return _internal_reserved_name(index);
}
inline std::string* DescriptorProto::mutable_reserved_name(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name)
  return _impl_.reserved_name_.Mutable(index);
}
inline void DescriptorProto::set_reserved_name(int index, const std::string& value) {
  _impl_.reserved_name_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::set_reserved_name(int index, std::string&& value) {
  _impl_.reserved_name_.Mutable(index)->assign(std::move(value));
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::set_reserved_name(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.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) {
  _impl_.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::_internal_add_reserved_name() {
  return _impl_.reserved_name_.Add();
}
inline void DescriptorProto::add_reserved_name(const std::string& value) {
  _impl_.reserved_name_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::add_reserved_name(std::string&& value) {
  _impl_.reserved_name_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
}
inline void DescriptorProto::add_reserved_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.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) {
  _impl_.reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.DescriptorProto.reserved_name)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
DescriptorProto::reserved_name() const {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name)
  return _impl_.reserved_name_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
DescriptorProto::mutable_reserved_name() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name)
  return &_impl_.reserved_name_;
}

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

// ExtensionRangeOptions

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

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

// FieldDescriptorProto

// optional string name = 1;
inline bool FieldDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool FieldDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void FieldDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FieldDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FieldDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
}
inline std::string* FieldDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
  return _s;
}
inline const std::string& FieldDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void FieldDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FieldDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
}

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

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

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

// optional string type_name = 6;
inline bool FieldDescriptorProto::_internal_has_type_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool FieldDescriptorProto::has_type_name() const {
  return _internal_has_type_name();
}
inline void FieldDescriptorProto::clear_type_name() {
  _impl_.type_name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& FieldDescriptorProto::type_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
  return _internal_type_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FieldDescriptorProto::set_type_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000004u;
 _impl_.type_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
}
inline std::string* FieldDescriptorProto::mutable_type_name() {
  std::string* _s = _internal_mutable_type_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
  return _s;
}
inline const std::string& FieldDescriptorProto::_internal_type_name() const {
  return _impl_.type_name_.Get();
}
inline void FieldDescriptorProto::_internal_set_type_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.type_name_.Set(value, GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::_internal_mutable_type_name() {
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.type_name_.Mutable(GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::release_type_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name)
  if (!_internal_has_type_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.type_name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.type_name_.IsDefault()) {
    _impl_.type_name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FieldDescriptorProto::set_allocated_type_name(std::string* type_name) {
  if (type_name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.type_name_.SetAllocated(type_name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.type_name_.IsDefault()) {
    _impl_.type_name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
}

// optional string extendee = 2;
inline bool FieldDescriptorProto::_internal_has_extendee() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool FieldDescriptorProto::has_extendee() const {
  return _internal_has_extendee();
}
inline void FieldDescriptorProto::clear_extendee() {
  _impl_.extendee_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& FieldDescriptorProto::extendee() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
  return _internal_extendee();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FieldDescriptorProto::set_extendee(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.extendee_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
}
inline std::string* FieldDescriptorProto::mutable_extendee() {
  std::string* _s = _internal_mutable_extendee();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
  return _s;
}
inline const std::string& FieldDescriptorProto::_internal_extendee() const {
  return _impl_.extendee_.Get();
}
inline void FieldDescriptorProto::_internal_set_extendee(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.extendee_.Set(value, GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::_internal_mutable_extendee() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.extendee_.Mutable(GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::release_extendee() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee)
  if (!_internal_has_extendee()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.extendee_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.extendee_.IsDefault()) {
    _impl_.extendee_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FieldDescriptorProto::set_allocated_extendee(std::string* extendee) {
  if (extendee != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.extendee_.SetAllocated(extendee, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.extendee_.IsDefault()) {
    _impl_.extendee_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
}

// optional string default_value = 7;
inline bool FieldDescriptorProto::_internal_has_default_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool FieldDescriptorProto::has_default_value() const {
  return _internal_has_default_value();
}
inline void FieldDescriptorProto::clear_default_value() {
  _impl_.default_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const std::string& FieldDescriptorProto::default_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
  return _internal_default_value();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FieldDescriptorProto::set_default_value(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000008u;
 _impl_.default_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
}
inline std::string* FieldDescriptorProto::mutable_default_value() {
  std::string* _s = _internal_mutable_default_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
  return _s;
}
inline const std::string& FieldDescriptorProto::_internal_default_value() const {
  return _impl_.default_value_.Get();
}
inline void FieldDescriptorProto::_internal_set_default_value(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.default_value_.Set(value, GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::_internal_mutable_default_value() {
  _impl_._has_bits_[0] |= 0x00000008u;
  return _impl_.default_value_.Mutable(GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::release_default_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value)
  if (!_internal_has_default_value()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000008u;
  auto* p = _impl_.default_value_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.default_value_.IsDefault()) {
    _impl_.default_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FieldDescriptorProto::set_allocated_default_value(std::string* default_value) {
  if (default_value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.default_value_.SetAllocated(default_value, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.default_value_.IsDefault()) {
    _impl_.default_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
}

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

// optional string json_name = 10;
inline bool FieldDescriptorProto::_internal_has_json_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool FieldDescriptorProto::has_json_name() const {
  return _internal_has_json_name();
}
inline void FieldDescriptorProto::clear_json_name() {
  _impl_.json_name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline const std::string& FieldDescriptorProto::json_name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.json_name)
  return _internal_json_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FieldDescriptorProto::set_json_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000010u;
 _impl_.json_name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name)
}
inline std::string* FieldDescriptorProto::mutable_json_name() {
  std::string* _s = _internal_mutable_json_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.json_name)
  return _s;
}
inline const std::string& FieldDescriptorProto::_internal_json_name() const {
  return _impl_.json_name_.Get();
}
inline void FieldDescriptorProto::_internal_set_json_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.json_name_.Set(value, GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::_internal_mutable_json_name() {
  _impl_._has_bits_[0] |= 0x00000010u;
  return _impl_.json_name_.Mutable(GetArenaForAllocation());
}
inline std::string* FieldDescriptorProto::release_json_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name)
  if (!_internal_has_json_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000010u;
  auto* p = _impl_.json_name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.json_name_.IsDefault()) {
    _impl_.json_name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FieldDescriptorProto::set_allocated_json_name(std::string* json_name) {
  if (json_name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.json_name_.SetAllocated(json_name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.json_name_.IsDefault()) {
    _impl_.json_name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.json_name)
}

// optional .google.protobuf.FieldOptions options = 8;
inline bool FieldDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool FieldDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void FieldDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000020u;
}
inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::FieldOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::FieldOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
  return _internal_options();
}
inline void FieldDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::FieldOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000020u;
  ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000020u;
  ::PROTOBUF_NAMESPACE_ID::FieldOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000020u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::FieldOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::FieldOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
  return _msg;
}
inline void FieldDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::FieldOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
}

// optional bool proto3_optional = 17;
inline bool FieldDescriptorProto::_internal_has_proto3_optional() const {
  bool value = (_impl_._has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool FieldDescriptorProto::has_proto3_optional() const {
  return _internal_has_proto3_optional();
}
inline void FieldDescriptorProto::clear_proto3_optional() {
  _impl_.proto3_optional_ = false;
  _impl_._has_bits_[0] &= ~0x00000100u;
}
inline bool FieldDescriptorProto::_internal_proto3_optional() const {
  return _impl_.proto3_optional_;
}
inline bool FieldDescriptorProto::proto3_optional() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.proto3_optional)
  return _internal_proto3_optional();
}
inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) {
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.proto3_optional_ = value;
}
inline void FieldDescriptorProto::set_proto3_optional(bool value) {
  _internal_set_proto3_optional(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional)
}

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

// OneofDescriptorProto

// optional string name = 1;
inline bool OneofDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool OneofDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void OneofDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& OneofDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void OneofDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
}
inline std::string* OneofDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
  return _s;
}
inline const std::string& OneofDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void OneofDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* OneofDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* OneofDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void OneofDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
}

// optional .google.protobuf.OneofOptions options = 2;
inline bool OneofDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool OneofDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void OneofDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::OneofOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::OneofOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options)
  return _internal_options();
}
inline void OneofDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::OneofOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::OneofOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000002u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::OneofOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::OneofOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options)
  return _msg;
}
inline void OneofDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::OneofOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options)
}

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

// EnumDescriptorProto_EnumReservedRange

// optional int32 start = 1;
inline bool EnumDescriptorProto_EnumReservedRange::_internal_has_start() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool EnumDescriptorProto_EnumReservedRange::has_start() const {
  return _internal_has_start();
}
inline void EnumDescriptorProto_EnumReservedRange::clear_start() {
  _impl_.start_ = 0;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const {
  return _impl_.start_;
}
inline int32_t EnumDescriptorProto_EnumReservedRange::start() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
  return _internal_start();
}
inline void EnumDescriptorProto_EnumReservedRange::_internal_set_start(int32_t value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.start_ = value;
}
inline void EnumDescriptorProto_EnumReservedRange::set_start(int32_t value) {
  _internal_set_start(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
}

// optional int32 end = 2;
inline bool EnumDescriptorProto_EnumReservedRange::_internal_has_end() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool EnumDescriptorProto_EnumReservedRange::has_end() const {
  return _internal_has_end();
}
inline void EnumDescriptorProto_EnumReservedRange::clear_end() {
  _impl_.end_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const {
  return _impl_.end_;
}
inline int32_t EnumDescriptorProto_EnumReservedRange::end() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
  return _internal_end();
}
inline void EnumDescriptorProto_EnumReservedRange::_internal_set_end(int32_t value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.end_ = value;
}
inline void EnumDescriptorProto_EnumReservedRange::set_end(int32_t value) {
  _internal_set_end(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
}

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

// EnumDescriptorProto

// optional string name = 1;
inline bool EnumDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool EnumDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void EnumDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& EnumDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void EnumDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
}
inline std::string* EnumDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
  return _s;
}
inline const std::string& EnumDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void EnumDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* EnumDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* EnumDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void EnumDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name)
}

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

// optional .google.protobuf.EnumOptions options = 3;
inline bool EnumDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool EnumDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void EnumDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::EnumOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::EnumOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
  return _internal_options();
}
inline void EnumDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::EnumOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::EnumOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000002u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::EnumOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
  return _msg;
}
inline void EnumDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
}

// repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
inline int EnumDescriptorProto::_internal_reserved_range_size() const {
  return _impl_.reserved_range_.size();
}
inline int EnumDescriptorProto::reserved_range_size() const {
  return _internal_reserved_range_size();
}
inline void EnumDescriptorProto::clear_reserved_range() {
  _impl_.reserved_range_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::mutable_reserved_range(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_range)
  return _impl_.reserved_range_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >*
EnumDescriptorProto::mutable_reserved_range() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_range)
  return &_impl_.reserved_range_;
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::_internal_reserved_range(int index) const {
  return _impl_.reserved_range_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::reserved_range(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_range)
  return _internal_reserved_range(index);
}
inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::_internal_add_reserved_range() {
  return _impl_.reserved_range_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::add_reserved_range() {
  ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange* _add = _internal_add_reserved_range();
  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_range)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >&
EnumDescriptorProto::reserved_range() const {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_range)
  return _impl_.reserved_range_;
}

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

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

// EnumValueDescriptorProto

// optional string name = 1;
inline bool EnumValueDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool EnumValueDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void EnumValueDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& EnumValueDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void EnumValueDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
}
inline std::string* EnumValueDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
  return _s;
}
inline const std::string& EnumValueDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void EnumValueDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* EnumValueDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* EnumValueDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void EnumValueDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
}

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

// optional .google.protobuf.EnumValueOptions options = 3;
inline bool EnumValueDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool EnumValueDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void EnumValueDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
  return _internal_options();
}
inline void EnumValueDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000002u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::EnumValueOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::EnumValueOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
  return _msg;
}
inline void EnumValueDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
}

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

// ServiceDescriptorProto

// optional string name = 1;
inline bool ServiceDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ServiceDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void ServiceDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ServiceDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void ServiceDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
}
inline std::string* ServiceDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
  return _s;
}
inline const std::string& ServiceDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void ServiceDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* ServiceDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* ServiceDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void ServiceDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name)
}

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

// optional .google.protobuf.ServiceOptions options = 3;
inline bool ServiceDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool ServiceDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void ServiceDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::ServiceOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::ServiceOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
  return _internal_options();
}
inline void ServiceDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::ServiceOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000002u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::ServiceOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::ServiceOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
  return _msg;
}
inline void ServiceDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::ServiceOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
}

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

// MethodDescriptorProto

// optional string name = 1;
inline bool MethodDescriptorProto::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool MethodDescriptorProto::has_name() const {
  return _internal_has_name();
}
inline void MethodDescriptorProto::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& MethodDescriptorProto::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void MethodDescriptorProto::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
}
inline std::string* MethodDescriptorProto::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
  return _s;
}
inline const std::string& MethodDescriptorProto::_internal_name() const {
  return _impl_.name_.Get();
}
inline void MethodDescriptorProto::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* MethodDescriptorProto::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* MethodDescriptorProto::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void MethodDescriptorProto::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
}

// optional string input_type = 2;
inline bool MethodDescriptorProto::_internal_has_input_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool MethodDescriptorProto::has_input_type() const {
  return _internal_has_input_type();
}
inline void MethodDescriptorProto::clear_input_type() {
  _impl_.input_type_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& MethodDescriptorProto::input_type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
  return _internal_input_type();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void MethodDescriptorProto::set_input_type(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.input_type_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
}
inline std::string* MethodDescriptorProto::mutable_input_type() {
  std::string* _s = _internal_mutable_input_type();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
  return _s;
}
inline const std::string& MethodDescriptorProto::_internal_input_type() const {
  return _impl_.input_type_.Get();
}
inline void MethodDescriptorProto::_internal_set_input_type(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.input_type_.Set(value, GetArenaForAllocation());
}
inline std::string* MethodDescriptorProto::_internal_mutable_input_type() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.input_type_.Mutable(GetArenaForAllocation());
}
inline std::string* MethodDescriptorProto::release_input_type() {
  // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type)
  if (!_internal_has_input_type()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.input_type_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.input_type_.IsDefault()) {
    _impl_.input_type_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void MethodDescriptorProto::set_allocated_input_type(std::string* input_type) {
  if (input_type != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.input_type_.SetAllocated(input_type, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.input_type_.IsDefault()) {
    _impl_.input_type_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
}

// optional string output_type = 3;
inline bool MethodDescriptorProto::_internal_has_output_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool MethodDescriptorProto::has_output_type() const {
  return _internal_has_output_type();
}
inline void MethodDescriptorProto::clear_output_type() {
  _impl_.output_type_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& MethodDescriptorProto::output_type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
  return _internal_output_type();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void MethodDescriptorProto::set_output_type(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000004u;
 _impl_.output_type_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
}
inline std::string* MethodDescriptorProto::mutable_output_type() {
  std::string* _s = _internal_mutable_output_type();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
  return _s;
}
inline const std::string& MethodDescriptorProto::_internal_output_type() const {
  return _impl_.output_type_.Get();
}
inline void MethodDescriptorProto::_internal_set_output_type(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.output_type_.Set(value, GetArenaForAllocation());
}
inline std::string* MethodDescriptorProto::_internal_mutable_output_type() {
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.output_type_.Mutable(GetArenaForAllocation());
}
inline std::string* MethodDescriptorProto::release_output_type() {
  // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type)
  if (!_internal_has_output_type()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.output_type_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.output_type_.IsDefault()) {
    _impl_.output_type_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void MethodDescriptorProto::set_allocated_output_type(std::string* output_type) {
  if (output_type != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.output_type_.SetAllocated(output_type, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.output_type_.IsDefault()) {
    _impl_.output_type_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
}

// optional .google.protobuf.MethodOptions options = 4;
inline bool MethodDescriptorProto::_internal_has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline bool MethodDescriptorProto::has_options() const {
  return _internal_has_options();
}
inline void MethodDescriptorProto::clear_options() {
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const {
  const ::PROTOBUF_NAMESPACE_ID::MethodOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::MethodOptions&>(
      ::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::options() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
  return _internal_options();
}
inline void MethodDescriptorProto::unsafe_arena_set_allocated_options(
    ::PROTOBUF_NAMESPACE_ID::MethodOptions* options) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = options;
  if (options) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000008u;
  ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::unsafe_arena_release_options() {
  // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options)
  _impl_._has_bits_[0] &= ~0x00000008u;
  ::PROTOBUF_NAMESPACE_ID::MethodOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::_internal_mutable_options() {
  _impl_._has_bits_[0] |= 0x00000008u;
  if (_impl_.options_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::MethodOptions>(GetArenaForAllocation());
    _impl_.options_ = p;
  }
  return _impl_.options_;
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::mutable_options() {
  ::PROTOBUF_NAMESPACE_ID::MethodOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
  return _msg;
}
inline void MethodDescriptorProto::set_allocated_options(::PROTOBUF_NAMESPACE_ID::MethodOptions* options) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.options_;
  }
  if (options) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(options);
    if (message_arena != submessage_arena) {
      options = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, options, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.options_ = options;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
}

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

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

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

// FileOptions

// optional string java_package = 1;
inline bool FileOptions::_internal_has_java_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool FileOptions::has_java_package() const {
  return _internal_has_java_package();
}
inline void FileOptions::clear_java_package() {
  _impl_.java_package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FileOptions::java_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
  return _internal_java_package();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_java_package(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.java_package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
}
inline std::string* FileOptions::mutable_java_package() {
  std::string* _s = _internal_mutable_java_package();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
  return _s;
}
inline const std::string& FileOptions::_internal_java_package() const {
  return _impl_.java_package_.Get();
}
inline void FileOptions::_internal_set_java_package(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.java_package_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_java_package() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.java_package_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_java_package() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package)
  if (!_internal_has_java_package()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.java_package_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.java_package_.IsDefault()) {
    _impl_.java_package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_java_package(std::string* java_package) {
  if (java_package != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.java_package_.SetAllocated(java_package, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.java_package_.IsDefault()) {
    _impl_.java_package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
}

// optional string java_outer_classname = 8;
inline bool FileOptions::_internal_has_java_outer_classname() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool FileOptions::has_java_outer_classname() const {
  return _internal_has_java_outer_classname();
}
inline void FileOptions::clear_java_outer_classname() {
  _impl_.java_outer_classname_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& FileOptions::java_outer_classname() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
  return _internal_java_outer_classname();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_java_outer_classname(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.java_outer_classname_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
}
inline std::string* FileOptions::mutable_java_outer_classname() {
  std::string* _s = _internal_mutable_java_outer_classname();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
  return _s;
}
inline const std::string& FileOptions::_internal_java_outer_classname() const {
  return _impl_.java_outer_classname_.Get();
}
inline void FileOptions::_internal_set_java_outer_classname(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.java_outer_classname_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_java_outer_classname() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.java_outer_classname_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_java_outer_classname() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname)
  if (!_internal_has_java_outer_classname()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.java_outer_classname_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.java_outer_classname_.IsDefault()) {
    _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_java_outer_classname(std::string* java_outer_classname) {
  if (java_outer_classname != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.java_outer_classname_.SetAllocated(java_outer_classname, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.java_outer_classname_.IsDefault()) {
    _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
}

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

// optional bool java_generate_equals_and_hash = 20 [deprecated = true];
inline bool FileOptions::_internal_has_java_generate_equals_and_hash() const {
  bool value = (_impl_._has_bits_[0] & 0x00000800u) != 0;
  return value;
}
inline bool FileOptions::has_java_generate_equals_and_hash() const {
  return _internal_has_java_generate_equals_and_hash();
}
inline void FileOptions::clear_java_generate_equals_and_hash() {
  _impl_.java_generate_equals_and_hash_ = false;
  _impl_._has_bits_[0] &= ~0x00000800u;
}
inline bool FileOptions::_internal_java_generate_equals_and_hash() const {
  return _impl_.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 _internal_java_generate_equals_and_hash();
}
inline void FileOptions::_internal_set_java_generate_equals_and_hash(bool value) {
  _impl_._has_bits_[0] |= 0x00000800u;
  _impl_.java_generate_equals_and_hash_ = value;
}
inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
  _internal_set_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::_internal_has_java_string_check_utf8() const {
  bool value = (_impl_._has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline bool FileOptions::has_java_string_check_utf8() const {
  return _internal_has_java_string_check_utf8();
}
inline void FileOptions::clear_java_string_check_utf8() {
  _impl_.java_string_check_utf8_ = false;
  _impl_._has_bits_[0] &= ~0x00001000u;
}
inline bool FileOptions::_internal_java_string_check_utf8() const {
  return _impl_.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 _internal_java_string_check_utf8();
}
inline void FileOptions::_internal_set_java_string_check_utf8(bool value) {
  _impl_._has_bits_[0] |= 0x00001000u;
  _impl_.java_string_check_utf8_ = value;
}
inline void FileOptions::set_java_string_check_utf8(bool value) {
  _internal_set_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::_internal_has_optimize_for() const {
  bool value = (_impl_._has_bits_[0] & 0x00040000u) != 0;
  return value;
}
inline bool FileOptions::has_optimize_for() const {
  return _internal_has_optimize_for();
}
inline void FileOptions::clear_optimize_for() {
  _impl_.optimize_for_ = 1;
  _impl_._has_bits_[0] &= ~0x00040000u;
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode >(_impl_.optimize_for_);
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::optimize_for() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
  return _internal_optimize_for();
}
inline void FileOptions::_internal_set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) {
  assert(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_IsValid(value));
  _impl_._has_bits_[0] |= 0x00040000u;
  _impl_.optimize_for_ = value;
}
inline void FileOptions::set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) {
  _internal_set_optimize_for(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
}

// optional string go_package = 11;
inline bool FileOptions::_internal_has_go_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool FileOptions::has_go_package() const {
  return _internal_has_go_package();
}
inline void FileOptions::clear_go_package() {
  _impl_.go_package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& FileOptions::go_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
  return _internal_go_package();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_go_package(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000004u;
 _impl_.go_package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
}
inline std::string* FileOptions::mutable_go_package() {
  std::string* _s = _internal_mutable_go_package();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
  return _s;
}
inline const std::string& FileOptions::_internal_go_package() const {
  return _impl_.go_package_.Get();
}
inline void FileOptions::_internal_set_go_package(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.go_package_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_go_package() {
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.go_package_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_go_package() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package)
  if (!_internal_has_go_package()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.go_package_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.go_package_.IsDefault()) {
    _impl_.go_package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_go_package(std::string* go_package) {
  if (go_package != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.go_package_.SetAllocated(go_package, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.go_package_.IsDefault()) {
    _impl_.go_package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
}

// optional bool cc_generic_services = 16 [default = false];
inline bool FileOptions::_internal_has_cc_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline bool FileOptions::has_cc_generic_services() const {
  return _internal_has_cc_generic_services();
}
inline void FileOptions::clear_cc_generic_services() {
  _impl_.cc_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00002000u;
}
inline bool FileOptions::_internal_cc_generic_services() const {
  return _impl_.cc_generic_services_;
}
inline bool FileOptions::cc_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
  return _internal_cc_generic_services();
}
inline void FileOptions::_internal_set_cc_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00002000u;
  _impl_.cc_generic_services_ = value;
}
inline void FileOptions::set_cc_generic_services(bool value) {
  _internal_set_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::_internal_has_java_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00004000u) != 0;
  return value;
}
inline bool FileOptions::has_java_generic_services() const {
  return _internal_has_java_generic_services();
}
inline void FileOptions::clear_java_generic_services() {
  _impl_.java_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00004000u;
}
inline bool FileOptions::_internal_java_generic_services() const {
  return _impl_.java_generic_services_;
}
inline bool FileOptions::java_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
  return _internal_java_generic_services();
}
inline void FileOptions::_internal_set_java_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00004000u;
  _impl_.java_generic_services_ = value;
}
inline void FileOptions::set_java_generic_services(bool value) {
  _internal_set_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::_internal_has_py_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00008000u) != 0;
  return value;
}
inline bool FileOptions::has_py_generic_services() const {
  return _internal_has_py_generic_services();
}
inline void FileOptions::clear_py_generic_services() {
  _impl_.py_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00008000u;
}
inline bool FileOptions::_internal_py_generic_services() const {
  return _impl_.py_generic_services_;
}
inline bool FileOptions::py_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
  return _internal_py_generic_services();
}
inline void FileOptions::_internal_set_py_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00008000u;
  _impl_.py_generic_services_ = value;
}
inline void FileOptions::set_py_generic_services(bool value) {
  _internal_set_py_generic_services(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
}

// optional bool php_generic_services = 42 [default = false];
inline bool FileOptions::_internal_has_php_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00010000u) != 0;
  return value;
}
inline bool FileOptions::has_php_generic_services() const {
  return _internal_has_php_generic_services();
}
inline void FileOptions::clear_php_generic_services() {
  _impl_.php_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00010000u;
}
inline bool FileOptions::_internal_php_generic_services() const {
  return _impl_.php_generic_services_;
}
inline bool FileOptions::php_generic_services() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_generic_services)
  return _internal_php_generic_services();
}
inline void FileOptions::_internal_set_php_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00010000u;
  _impl_.php_generic_services_ = value;
}
inline void FileOptions::set_php_generic_services(bool value) {
  _internal_set_php_generic_services(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services)
}

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

// optional bool cc_enable_arenas = 31 [default = true];
inline bool FileOptions::_internal_has_cc_enable_arenas() const {
  bool value = (_impl_._has_bits_[0] & 0x00080000u) != 0;
  return value;
}
inline bool FileOptions::has_cc_enable_arenas() const {
  return _internal_has_cc_enable_arenas();
}
inline void FileOptions::clear_cc_enable_arenas() {
  _impl_.cc_enable_arenas_ = true;
  _impl_._has_bits_[0] &= ~0x00080000u;
}
inline bool FileOptions::_internal_cc_enable_arenas() const {
  return _impl_.cc_enable_arenas_;
}
inline bool FileOptions::cc_enable_arenas() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas)
  return _internal_cc_enable_arenas();
}
inline void FileOptions::_internal_set_cc_enable_arenas(bool value) {
  _impl_._has_bits_[0] |= 0x00080000u;
  _impl_.cc_enable_arenas_ = value;
}
inline void FileOptions::set_cc_enable_arenas(bool value) {
  _internal_set_cc_enable_arenas(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
}

// optional string objc_class_prefix = 36;
inline bool FileOptions::_internal_has_objc_class_prefix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool FileOptions::has_objc_class_prefix() const {
  return _internal_has_objc_class_prefix();
}
inline void FileOptions::clear_objc_class_prefix() {
  _impl_.objc_class_prefix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const std::string& FileOptions::objc_class_prefix() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix)
  return _internal_objc_class_prefix();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_objc_class_prefix(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000008u;
 _impl_.objc_class_prefix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
}
inline std::string* FileOptions::mutable_objc_class_prefix() {
  std::string* _s = _internal_mutable_objc_class_prefix();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix)
  return _s;
}
inline const std::string& FileOptions::_internal_objc_class_prefix() const {
  return _impl_.objc_class_prefix_.Get();
}
inline void FileOptions::_internal_set_objc_class_prefix(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.objc_class_prefix_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_objc_class_prefix() {
  _impl_._has_bits_[0] |= 0x00000008u;
  return _impl_.objc_class_prefix_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_objc_class_prefix() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix)
  if (!_internal_has_objc_class_prefix()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000008u;
  auto* p = _impl_.objc_class_prefix_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.objc_class_prefix_.IsDefault()) {
    _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_objc_class_prefix(std::string* objc_class_prefix) {
  if (objc_class_prefix != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.objc_class_prefix_.SetAllocated(objc_class_prefix, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.objc_class_prefix_.IsDefault()) {
    _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
}

// optional string csharp_namespace = 37;
inline bool FileOptions::_internal_has_csharp_namespace() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool FileOptions::has_csharp_namespace() const {
  return _internal_has_csharp_namespace();
}
inline void FileOptions::clear_csharp_namespace() {
  _impl_.csharp_namespace_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline const std::string& FileOptions::csharp_namespace() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace)
  return _internal_csharp_namespace();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_csharp_namespace(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000010u;
 _impl_.csharp_namespace_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
}
inline std::string* FileOptions::mutable_csharp_namespace() {
  std::string* _s = _internal_mutable_csharp_namespace();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
  return _s;
}
inline const std::string& FileOptions::_internal_csharp_namespace() const {
  return _impl_.csharp_namespace_.Get();
}
inline void FileOptions::_internal_set_csharp_namespace(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.csharp_namespace_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_csharp_namespace() {
  _impl_._has_bits_[0] |= 0x00000010u;
  return _impl_.csharp_namespace_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_csharp_namespace() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace)
  if (!_internal_has_csharp_namespace()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000010u;
  auto* p = _impl_.csharp_namespace_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.csharp_namespace_.IsDefault()) {
    _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_csharp_namespace(std::string* csharp_namespace) {
  if (csharp_namespace != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.csharp_namespace_.SetAllocated(csharp_namespace, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.csharp_namespace_.IsDefault()) {
    _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
}

// optional string swift_prefix = 39;
inline bool FileOptions::_internal_has_swift_prefix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool FileOptions::has_swift_prefix() const {
  return _internal_has_swift_prefix();
}
inline void FileOptions::clear_swift_prefix() {
  _impl_.swift_prefix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000020u;
}
inline const std::string& FileOptions::swift_prefix() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.swift_prefix)
  return _internal_swift_prefix();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_swift_prefix(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000020u;
 _impl_.swift_prefix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.swift_prefix)
}
inline std::string* FileOptions::mutable_swift_prefix() {
  std::string* _s = _internal_mutable_swift_prefix();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.swift_prefix)
  return _s;
}
inline const std::string& FileOptions::_internal_swift_prefix() const {
  return _impl_.swift_prefix_.Get();
}
inline void FileOptions::_internal_set_swift_prefix(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000020u;
  _impl_.swift_prefix_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_swift_prefix() {
  _impl_._has_bits_[0] |= 0x00000020u;
  return _impl_.swift_prefix_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_swift_prefix() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.swift_prefix)
  if (!_internal_has_swift_prefix()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000020u;
  auto* p = _impl_.swift_prefix_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.swift_prefix_.IsDefault()) {
    _impl_.swift_prefix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_swift_prefix(std::string* swift_prefix) {
  if (swift_prefix != nullptr) {
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  _impl_.swift_prefix_.SetAllocated(swift_prefix, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.swift_prefix_.IsDefault()) {
    _impl_.swift_prefix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.swift_prefix)
}

// optional string php_class_prefix = 40;
inline bool FileOptions::_internal_has_php_class_prefix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool FileOptions::has_php_class_prefix() const {
  return _internal_has_php_class_prefix();
}
inline void FileOptions::clear_php_class_prefix() {
  _impl_.php_class_prefix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000040u;
}
inline const std::string& FileOptions::php_class_prefix() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_class_prefix)
  return _internal_php_class_prefix();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_php_class_prefix(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000040u;
 _impl_.php_class_prefix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix)
}
inline std::string* FileOptions::mutable_php_class_prefix() {
  std::string* _s = _internal_mutable_php_class_prefix();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_class_prefix)
  return _s;
}
inline const std::string& FileOptions::_internal_php_class_prefix() const {
  return _impl_.php_class_prefix_.Get();
}
inline void FileOptions::_internal_set_php_class_prefix(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000040u;
  _impl_.php_class_prefix_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_php_class_prefix() {
  _impl_._has_bits_[0] |= 0x00000040u;
  return _impl_.php_class_prefix_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_php_class_prefix() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix)
  if (!_internal_has_php_class_prefix()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000040u;
  auto* p = _impl_.php_class_prefix_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.php_class_prefix_.IsDefault()) {
    _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_php_class_prefix(std::string* php_class_prefix) {
  if (php_class_prefix != nullptr) {
    _impl_._has_bits_[0] |= 0x00000040u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000040u;
  }
  _impl_.php_class_prefix_.SetAllocated(php_class_prefix, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.php_class_prefix_.IsDefault()) {
    _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix)
}

// optional string php_namespace = 41;
inline bool FileOptions::_internal_has_php_namespace() const {
  bool value = (_impl_._has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool FileOptions::has_php_namespace() const {
  return _internal_has_php_namespace();
}
inline void FileOptions::clear_php_namespace() {
  _impl_.php_namespace_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000080u;
}
inline const std::string& FileOptions::php_namespace() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_namespace)
  return _internal_php_namespace();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_php_namespace(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000080u;
 _impl_.php_namespace_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
}
inline std::string* FileOptions::mutable_php_namespace() {
  std::string* _s = _internal_mutable_php_namespace();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_namespace)
  return _s;
}
inline const std::string& FileOptions::_internal_php_namespace() const {
  return _impl_.php_namespace_.Get();
}
inline void FileOptions::_internal_set_php_namespace(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000080u;
  _impl_.php_namespace_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_php_namespace() {
  _impl_._has_bits_[0] |= 0x00000080u;
  return _impl_.php_namespace_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_php_namespace() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace)
  if (!_internal_has_php_namespace()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000080u;
  auto* p = _impl_.php_namespace_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.php_namespace_.IsDefault()) {
    _impl_.php_namespace_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_php_namespace(std::string* php_namespace) {
  if (php_namespace != nullptr) {
    _impl_._has_bits_[0] |= 0x00000080u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000080u;
  }
  _impl_.php_namespace_.SetAllocated(php_namespace, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.php_namespace_.IsDefault()) {
    _impl_.php_namespace_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_namespace)
}

// optional string php_metadata_namespace = 44;
inline bool FileOptions::_internal_has_php_metadata_namespace() const {
  bool value = (_impl_._has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool FileOptions::has_php_metadata_namespace() const {
  return _internal_has_php_metadata_namespace();
}
inline void FileOptions::clear_php_metadata_namespace() {
  _impl_.php_metadata_namespace_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000100u;
}
inline const std::string& FileOptions::php_metadata_namespace() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_metadata_namespace)
  return _internal_php_metadata_namespace();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_php_metadata_namespace(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000100u;
 _impl_.php_metadata_namespace_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_metadata_namespace)
}
inline std::string* FileOptions::mutable_php_metadata_namespace() {
  std::string* _s = _internal_mutable_php_metadata_namespace();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_metadata_namespace)
  return _s;
}
inline const std::string& FileOptions::_internal_php_metadata_namespace() const {
  return _impl_.php_metadata_namespace_.Get();
}
inline void FileOptions::_internal_set_php_metadata_namespace(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.php_metadata_namespace_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() {
  _impl_._has_bits_[0] |= 0x00000100u;
  return _impl_.php_metadata_namespace_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_php_metadata_namespace() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_metadata_namespace)
  if (!_internal_has_php_metadata_namespace()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000100u;
  auto* p = _impl_.php_metadata_namespace_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.php_metadata_namespace_.IsDefault()) {
    _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_php_metadata_namespace(std::string* php_metadata_namespace) {
  if (php_metadata_namespace != nullptr) {
    _impl_._has_bits_[0] |= 0x00000100u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000100u;
  }
  _impl_.php_metadata_namespace_.SetAllocated(php_metadata_namespace, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.php_metadata_namespace_.IsDefault()) {
    _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_metadata_namespace)
}

// optional string ruby_package = 45;
inline bool FileOptions::_internal_has_ruby_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool FileOptions::has_ruby_package() const {
  return _internal_has_ruby_package();
}
inline void FileOptions::clear_ruby_package() {
  _impl_.ruby_package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000200u;
}
inline const std::string& FileOptions::ruby_package() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.ruby_package)
  return _internal_ruby_package();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileOptions::set_ruby_package(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000200u;
 _impl_.ruby_package_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.ruby_package)
}
inline std::string* FileOptions::mutable_ruby_package() {
  std::string* _s = _internal_mutable_ruby_package();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.ruby_package)
  return _s;
}
inline const std::string& FileOptions::_internal_ruby_package() const {
  return _impl_.ruby_package_.Get();
}
inline void FileOptions::_internal_set_ruby_package(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000200u;
  _impl_.ruby_package_.Set(value, GetArenaForAllocation());
}
inline std::string* FileOptions::_internal_mutable_ruby_package() {
  _impl_._has_bits_[0] |= 0x00000200u;
  return _impl_.ruby_package_.Mutable(GetArenaForAllocation());
}
inline std::string* FileOptions::release_ruby_package() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.ruby_package)
  if (!_internal_has_ruby_package()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000200u;
  auto* p = _impl_.ruby_package_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.ruby_package_.IsDefault()) {
    _impl_.ruby_package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileOptions::set_allocated_ruby_package(std::string* ruby_package) {
  if (ruby_package != nullptr) {
    _impl_._has_bits_[0] |= 0x00000200u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000200u;
  }
  _impl_.ruby_package_.SetAllocated(ruby_package, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.ruby_package_.IsDefault()) {
    _impl_.ruby_package_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.ruby_package)
}

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

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

// MessageOptions

// optional bool message_set_wire_format = 1 [default = false];
inline bool MessageOptions::_internal_has_message_set_wire_format() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool MessageOptions::has_message_set_wire_format() const {
  return _internal_has_message_set_wire_format();
}
inline void MessageOptions::clear_message_set_wire_format() {
  _impl_.message_set_wire_format_ = false;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline bool MessageOptions::_internal_message_set_wire_format() const {
  return _impl_.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 _internal_message_set_wire_format();
}
inline void MessageOptions::_internal_set_message_set_wire_format(bool value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.message_set_wire_format_ = value;
}
inline void MessageOptions::set_message_set_wire_format(bool value) {
  _internal_set_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::_internal_has_no_standard_descriptor_accessor() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
  return _internal_has_no_standard_descriptor_accessor();
}
inline void MessageOptions::clear_no_standard_descriptor_accessor() {
  _impl_.no_standard_descriptor_accessor_ = false;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const {
  return _impl_.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 _internal_no_standard_descriptor_accessor();
}
inline void MessageOptions::_internal_set_no_standard_descriptor_accessor(bool value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.no_standard_descriptor_accessor_ = value;
}
inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
  _internal_set_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::_internal_has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool MessageOptions::has_deprecated() const {
  return _internal_has_deprecated();
}
inline void MessageOptions::clear_deprecated() {
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline bool MessageOptions::_internal_deprecated() const {
  return _impl_.deprecated_;
}
inline bool MessageOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
  return _internal_deprecated();
}
inline void MessageOptions::_internal_set_deprecated(bool value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.deprecated_ = value;
}
inline void MessageOptions::set_deprecated(bool value) {
  _internal_set_deprecated(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
}

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

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

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

// FieldOptions

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

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

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

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

// optional bool unverified_lazy = 15 [default = false];
inline bool FieldOptions::_internal_has_unverified_lazy() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool FieldOptions::has_unverified_lazy() const {
  return _internal_has_unverified_lazy();
}
inline void FieldOptions::clear_unverified_lazy() {
  _impl_.unverified_lazy_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline bool FieldOptions::_internal_unverified_lazy() const {
  return _impl_.unverified_lazy_;
}
inline bool FieldOptions::unverified_lazy() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.unverified_lazy)
  return _internal_unverified_lazy();
}
inline void FieldOptions::_internal_set_unverified_lazy(bool value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.unverified_lazy_ = value;
}
inline void FieldOptions::set_unverified_lazy(bool value) {
  _internal_set_unverified_lazy(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.unverified_lazy)
}

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

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

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

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

// OneofOptions

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

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

// EnumOptions

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

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

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

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

// EnumValueOptions

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

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

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

// ServiceOptions

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

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

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

// MethodOptions

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

// optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
inline bool MethodOptions::_internal_has_idempotency_level() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool MethodOptions::has_idempotency_level() const {
  return _internal_has_idempotency_level();
}
inline void MethodOptions::clear_idempotency_level() {
  _impl_.idempotency_level_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel >(_impl_.idempotency_level_);
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::idempotency_level() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.idempotency_level)
  return _internal_idempotency_level();
}
inline void MethodOptions::_internal_set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) {
  assert(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_IsValid(value));
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.idempotency_level_ = value;
}
inline void MethodOptions::set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) {
  _internal_set_idempotency_level(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level)
}

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

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

// UninterpretedOption_NamePart

// required string name_part = 1;
inline bool UninterpretedOption_NamePart::_internal_has_name_part() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool UninterpretedOption_NamePart::has_name_part() const {
  return _internal_has_name_part();
}
inline void UninterpretedOption_NamePart::clear_name_part() {
  _impl_.name_part_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& UninterpretedOption_NamePart::name_part() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
  return _internal_name_part();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void UninterpretedOption_NamePart::set_name_part(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_part_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline std::string* UninterpretedOption_NamePart::mutable_name_part() {
  std::string* _s = _internal_mutable_name_part();
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
  return _s;
}
inline const std::string& UninterpretedOption_NamePart::_internal_name_part() const {
  return _impl_.name_part_.Get();
}
inline void UninterpretedOption_NamePart::_internal_set_name_part(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_part_.Set(value, GetArenaForAllocation());
}
inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_part_.Mutable(GetArenaForAllocation());
}
inline std::string* UninterpretedOption_NamePart::release_name_part() {
  // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part)
  if (!_internal_has_name_part()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_part_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_part_.IsDefault()) {
    _impl_.name_part_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* name_part) {
  if (name_part != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_part_.SetAllocated(name_part, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_part_.IsDefault()) {
    _impl_.name_part_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
}

// required bool is_extension = 2;
inline bool UninterpretedOption_NamePart::_internal_has_is_extension() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool UninterpretedOption_NamePart::has_is_extension() const {
  return _internal_has_is_extension();
}
inline void UninterpretedOption_NamePart::clear_is_extension() {
  _impl_.is_extension_ = false;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline bool UninterpretedOption_NamePart::_internal_is_extension() const {
  return _impl_.is_extension_;
}
inline bool UninterpretedOption_NamePart::is_extension() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
  return _internal_is_extension();
}
inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.is_extension_ = value;
}
inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
  _internal_set_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::_internal_name_size() const {
  return _impl_.name_.size();
}
inline int UninterpretedOption::name_size() const {
  return _internal_name_size();
}
inline void UninterpretedOption::clear_name() {
  _impl_.name_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
  return _impl_.name_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >*
UninterpretedOption::mutable_name() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
  return &_impl_.name_;
}
inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::_internal_name(int index) const {
  return _impl_.name_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
  return _internal_name(index);
}
inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::_internal_add_name() {
  return _impl_.name_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
  ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart* _add = _internal_add_name();
  // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >&
UninterpretedOption::name() const {
  // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
  return _impl_.name_;
}

// optional string identifier_value = 3;
inline bool UninterpretedOption::_internal_has_identifier_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool UninterpretedOption::has_identifier_value() const {
  return _internal_has_identifier_value();
}
inline void UninterpretedOption::clear_identifier_value() {
  _impl_.identifier_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& UninterpretedOption::identifier_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
  return _internal_identifier_value();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void UninterpretedOption::set_identifier_value(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.identifier_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
}
inline std::string* UninterpretedOption::mutable_identifier_value() {
  std::string* _s = _internal_mutable_identifier_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
  return _s;
}
inline const std::string& UninterpretedOption::_internal_identifier_value() const {
  return _impl_.identifier_value_.Get();
}
inline void UninterpretedOption::_internal_set_identifier_value(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.identifier_value_.Set(value, GetArenaForAllocation());
}
inline std::string* UninterpretedOption::_internal_mutable_identifier_value() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.identifier_value_.Mutable(GetArenaForAllocation());
}
inline std::string* UninterpretedOption::release_identifier_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value)
  if (!_internal_has_identifier_value()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.identifier_value_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.identifier_value_.IsDefault()) {
    _impl_.identifier_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void UninterpretedOption::set_allocated_identifier_value(std::string* identifier_value) {
  if (identifier_value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.identifier_value_.SetAllocated(identifier_value, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.identifier_value_.IsDefault()) {
    _impl_.identifier_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
}

// optional uint64 positive_int_value = 4;
inline bool UninterpretedOption::_internal_has_positive_int_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool UninterpretedOption::has_positive_int_value() const {
  return _internal_has_positive_int_value();
}
inline void UninterpretedOption::clear_positive_int_value() {
  _impl_.positive_int_value_ = uint64_t{0u};
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline uint64_t UninterpretedOption::_internal_positive_int_value() const {
  return _impl_.positive_int_value_;
}
inline uint64_t UninterpretedOption::positive_int_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
  return _internal_positive_int_value();
}
inline void UninterpretedOption::_internal_set_positive_int_value(uint64_t value) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.positive_int_value_ = value;
}
inline void UninterpretedOption::set_positive_int_value(uint64_t value) {
  _internal_set_positive_int_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
}

// optional int64 negative_int_value = 5;
inline bool UninterpretedOption::_internal_has_negative_int_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool UninterpretedOption::has_negative_int_value() const {
  return _internal_has_negative_int_value();
}
inline void UninterpretedOption::clear_negative_int_value() {
  _impl_.negative_int_value_ = int64_t{0};
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline int64_t UninterpretedOption::_internal_negative_int_value() const {
  return _impl_.negative_int_value_;
}
inline int64_t UninterpretedOption::negative_int_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
  return _internal_negative_int_value();
}
inline void UninterpretedOption::_internal_set_negative_int_value(int64_t value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.negative_int_value_ = value;
}
inline void UninterpretedOption::set_negative_int_value(int64_t value) {
  _internal_set_negative_int_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
}

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

// optional bytes string_value = 7;
inline bool UninterpretedOption::_internal_has_string_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool UninterpretedOption::has_string_value() const {
  return _internal_has_string_value();
}
inline void UninterpretedOption::clear_string_value() {
  _impl_.string_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& UninterpretedOption::string_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
  return _internal_string_value();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void UninterpretedOption::set_string_value(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.string_value_.SetBytes(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
}
inline std::string* UninterpretedOption::mutable_string_value() {
  std::string* _s = _internal_mutable_string_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
  return _s;
}
inline const std::string& UninterpretedOption::_internal_string_value() const {
  return _impl_.string_value_.Get();
}
inline void UninterpretedOption::_internal_set_string_value(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.string_value_.Set(value, GetArenaForAllocation());
}
inline std::string* UninterpretedOption::_internal_mutable_string_value() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.string_value_.Mutable(GetArenaForAllocation());
}
inline std::string* UninterpretedOption::release_string_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value)
  if (!_internal_has_string_value()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.string_value_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.string_value_.IsDefault()) {
    _impl_.string_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void UninterpretedOption::set_allocated_string_value(std::string* string_value) {
  if (string_value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.string_value_.SetAllocated(string_value, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.string_value_.IsDefault()) {
    _impl_.string_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
}

// optional string aggregate_value = 8;
inline bool UninterpretedOption::_internal_has_aggregate_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool UninterpretedOption::has_aggregate_value() const {
  return _internal_has_aggregate_value();
}
inline void UninterpretedOption::clear_aggregate_value() {
  _impl_.aggregate_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& UninterpretedOption::aggregate_value() const {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
  return _internal_aggregate_value();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void UninterpretedOption::set_aggregate_value(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000004u;
 _impl_.aggregate_value_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
}
inline std::string* UninterpretedOption::mutable_aggregate_value() {
  std::string* _s = _internal_mutable_aggregate_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
  return _s;
}
inline const std::string& UninterpretedOption::_internal_aggregate_value() const {
  return _impl_.aggregate_value_.Get();
}
inline void UninterpretedOption::_internal_set_aggregate_value(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.aggregate_value_.Set(value, GetArenaForAllocation());
}
inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() {
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.aggregate_value_.Mutable(GetArenaForAllocation());
}
inline std::string* UninterpretedOption::release_aggregate_value() {
  // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value)
  if (!_internal_has_aggregate_value()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.aggregate_value_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.aggregate_value_.IsDefault()) {
    _impl_.aggregate_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void UninterpretedOption::set_allocated_aggregate_value(std::string* aggregate_value) {
  if (aggregate_value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.aggregate_value_.SetAllocated(aggregate_value, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.aggregate_value_.IsDefault()) {
    _impl_.aggregate_value_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
}

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

// SourceCodeInfo_Location

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

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

// optional string leading_comments = 3;
inline bool SourceCodeInfo_Location::_internal_has_leading_comments() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool SourceCodeInfo_Location::has_leading_comments() const {
  return _internal_has_leading_comments();
}
inline void SourceCodeInfo_Location::clear_leading_comments() {
  _impl_.leading_comments_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& SourceCodeInfo_Location::leading_comments() const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
  return _internal_leading_comments();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void SourceCodeInfo_Location::set_leading_comments(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.leading_comments_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
}
inline std::string* SourceCodeInfo_Location::mutable_leading_comments() {
  std::string* _s = _internal_mutable_leading_comments();
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
  return _s;
}
inline const std::string& SourceCodeInfo_Location::_internal_leading_comments() const {
  return _impl_.leading_comments_.Get();
}
inline void SourceCodeInfo_Location::_internal_set_leading_comments(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.leading_comments_.Set(value, GetArenaForAllocation());
}
inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.leading_comments_.Mutable(GetArenaForAllocation());
}
inline std::string* SourceCodeInfo_Location::release_leading_comments() {
  // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments)
  if (!_internal_has_leading_comments()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.leading_comments_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.leading_comments_.IsDefault()) {
    _impl_.leading_comments_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* leading_comments) {
  if (leading_comments != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.leading_comments_.SetAllocated(leading_comments, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.leading_comments_.IsDefault()) {
    _impl_.leading_comments_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
}

// optional string trailing_comments = 4;
inline bool SourceCodeInfo_Location::_internal_has_trailing_comments() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool SourceCodeInfo_Location::has_trailing_comments() const {
  return _internal_has_trailing_comments();
}
inline void SourceCodeInfo_Location::clear_trailing_comments() {
  _impl_.trailing_comments_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& SourceCodeInfo_Location::trailing_comments() const {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
  return _internal_trailing_comments();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void SourceCodeInfo_Location::set_trailing_comments(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.trailing_comments_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}
inline std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
  std::string* _s = _internal_mutable_trailing_comments();
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
  return _s;
}
inline const std::string& SourceCodeInfo_Location::_internal_trailing_comments() const {
  return _impl_.trailing_comments_.Get();
}
inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.trailing_comments_.Set(value, GetArenaForAllocation());
}
inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.trailing_comments_.Mutable(GetArenaForAllocation());
}
inline std::string* SourceCodeInfo_Location::release_trailing_comments() {
  // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments)
  if (!_internal_has_trailing_comments()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.trailing_comments_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.trailing_comments_.IsDefault()) {
    _impl_.trailing_comments_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* trailing_comments) {
  if (trailing_comments != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.trailing_comments_.SetAllocated(trailing_comments, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.trailing_comments_.IsDefault()) {
    _impl_.trailing_comments_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}

// repeated string leading_detached_comments = 6;
inline int SourceCodeInfo_Location::_internal_leading_detached_comments_size() const {
  return _impl_.leading_detached_comments_.size();
}
inline int SourceCodeInfo_Location::leading_detached_comments_size() const {
  return _internal_leading_detached_comments_size();
}
inline void SourceCodeInfo_Location::clear_leading_detached_comments() {
  _impl_.leading_detached_comments_.Clear();
}
inline std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
  std::string* _s = _internal_add_leading_detached_comments();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return _s;
}
inline const std::string& SourceCodeInfo_Location::_internal_leading_detached_comments(int index) const {
  return _impl_.leading_detached_comments_.Get(index);
}
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 _internal_leading_detached_comments(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 _impl_.leading_detached_comments_.Mutable(index);
}
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const std::string& value) {
  _impl_.leading_detached_comments_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, std::string&& value) {
  _impl_.leading_detached_comments_.Mutable(index)->assign(std::move(value));
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.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) {
  _impl_.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::_internal_add_leading_detached_comments() {
  return _impl_.leading_detached_comments_.Add();
}
inline void SourceCodeInfo_Location::add_leading_detached_comments(const std::string& value) {
  _impl_.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(std::string&& value) {
  _impl_.leading_detached_comments_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.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) {
  _impl_.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 ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
SourceCodeInfo_Location::leading_detached_comments() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return _impl_.leading_detached_comments_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
SourceCodeInfo_Location::mutable_leading_detached_comments() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return &_impl_.leading_detached_comments_;
}

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

// SourceCodeInfo

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

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

// GeneratedCodeInfo_Annotation

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

// optional string source_file = 2;
inline bool GeneratedCodeInfo_Annotation::_internal_has_source_file() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool GeneratedCodeInfo_Annotation::has_source_file() const {
  return _internal_has_source_file();
}
inline void GeneratedCodeInfo_Annotation::clear_source_file() {
  _impl_.source_file_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& GeneratedCodeInfo_Annotation::source_file() const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
  return _internal_source_file();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void GeneratedCodeInfo_Annotation::set_source_file(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.source_file_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}
inline std::string* GeneratedCodeInfo_Annotation::mutable_source_file() {
  std::string* _s = _internal_mutable_source_file();
  // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
  return _s;
}
inline const std::string& GeneratedCodeInfo_Annotation::_internal_source_file() const {
  return _impl_.source_file_.Get();
}
inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.source_file_.Set(value, GetArenaForAllocation());
}
inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.source_file_.Mutable(GetArenaForAllocation());
}
inline std::string* GeneratedCodeInfo_Annotation::release_source_file() {
  // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
  if (!_internal_has_source_file()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.source_file_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.source_file_.IsDefault()) {
    _impl_.source_file_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* source_file) {
  if (source_file != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.source_file_.SetAllocated(source_file, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.source_file_.IsDefault()) {
    _impl_.source_file_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}

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

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

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

// GeneratedCodeInfo

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

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

PROTOBUF_NAMESPACE_CLOSE

PROTOBUF_NAMESPACE_OPEN

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

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
