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

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh

#include <limits>
#include <string>
#include <type_traits>

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

#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  // PROTOBUF_MIN_PROTOC_VERSION
#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)

// Must be included last.
#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_;
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 = static_cast<FieldDescriptorProto_Type>(1);
constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = static_cast<FieldDescriptorProto_Type>(18);
constexpr int FieldDescriptorProto_Type_Type_ARRAYSIZE = 18 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FieldDescriptorProto_Type_descriptor();
template <typename T>
const std::string& FieldDescriptorProto_Type_Name(T value) {
  static_assert(std::is_same<T, FieldDescriptorProto_Type>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to Type_Name().");
  return FieldDescriptorProto_Type_Name(static_cast<FieldDescriptorProto_Type>(value));
}
template <>
inline const std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FieldDescriptorProto_Type_descriptor,
                                                 1, 18>(
      static_cast<int>(value));
}
inline bool FieldDescriptorProto_Type_Parse(absl::string_view 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 = static_cast<FieldDescriptorProto_Label>(1);
constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = static_cast<FieldDescriptorProto_Label>(3);
constexpr int FieldDescriptorProto_Label_Label_ARRAYSIZE = 3 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FieldDescriptorProto_Label_descriptor();
template <typename T>
const std::string& FieldDescriptorProto_Label_Name(T value) {
  static_assert(std::is_same<T, FieldDescriptorProto_Label>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to Label_Name().");
  return FieldDescriptorProto_Label_Name(static_cast<FieldDescriptorProto_Label>(value));
}
template <>
inline const std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FieldDescriptorProto_Label_descriptor,
                                                 1, 3>(
      static_cast<int>(value));
}
inline bool FieldDescriptorProto_Label_Parse(absl::string_view 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 = static_cast<FileOptions_OptimizeMode>(1);
constexpr FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = static_cast<FileOptions_OptimizeMode>(3);
constexpr int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = 3 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FileOptions_OptimizeMode_descriptor();
template <typename T>
const std::string& FileOptions_OptimizeMode_Name(T value) {
  static_assert(std::is_same<T, FileOptions_OptimizeMode>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to OptimizeMode_Name().");
  return FileOptions_OptimizeMode_Name(static_cast<FileOptions_OptimizeMode>(value));
}
template <>
inline const std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FileOptions_OptimizeMode_descriptor,
                                                 1, 3>(
      static_cast<int>(value));
}
inline bool FileOptions_OptimizeMode_Parse(absl::string_view 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 = static_cast<FieldOptions_CType>(0);
constexpr FieldOptions_CType FieldOptions_CType_CType_MAX = static_cast<FieldOptions_CType>(2);
constexpr int FieldOptions_CType_CType_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FieldOptions_CType_descriptor();
template <typename T>
const std::string& FieldOptions_CType_Name(T value) {
  static_assert(std::is_same<T, FieldOptions_CType>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to CType_Name().");
  return FieldOptions_CType_Name(static_cast<FieldOptions_CType>(value));
}
template <>
inline const std::string& FieldOptions_CType_Name(FieldOptions_CType value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FieldOptions_CType_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FieldOptions_CType_Parse(absl::string_view 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 = static_cast<FieldOptions_JSType>(0);
constexpr FieldOptions_JSType FieldOptions_JSType_JSType_MAX = static_cast<FieldOptions_JSType>(2);
constexpr int FieldOptions_JSType_JSType_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FieldOptions_JSType_descriptor();
template <typename T>
const std::string& FieldOptions_JSType_Name(T value) {
  static_assert(std::is_same<T, FieldOptions_JSType>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to JSType_Name().");
  return FieldOptions_JSType_Name(static_cast<FieldOptions_JSType>(value));
}
template <>
inline const std::string& FieldOptions_JSType_Name(FieldOptions_JSType value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FieldOptions_JSType_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FieldOptions_JSType_Parse(absl::string_view 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 = static_cast<MethodOptions_IdempotencyLevel>(0);
constexpr MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel_IdempotencyLevel_MAX = static_cast<MethodOptions_IdempotencyLevel>(2);
constexpr int MethodOptions_IdempotencyLevel_IdempotencyLevel_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
MethodOptions_IdempotencyLevel_descriptor();
template <typename T>
const std::string& MethodOptions_IdempotencyLevel_Name(T value) {
  static_assert(std::is_same<T, MethodOptions_IdempotencyLevel>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to IdempotencyLevel_Name().");
  return MethodOptions_IdempotencyLevel_Name(static_cast<MethodOptions_IdempotencyLevel>(value));
}
template <>
inline const std::string& MethodOptions_IdempotencyLevel_Name(MethodOptions_IdempotencyLevel value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<MethodOptions_IdempotencyLevel_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool MethodOptions_IdempotencyLevel_Parse(absl::string_view name, MethodOptions_IdempotencyLevel* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<MethodOptions_IdempotencyLevel>(
      MethodOptions_IdempotencyLevel_descriptor(), name, value);
}
enum GeneratedCodeInfo_Annotation_Semantic : int {
  GeneratedCodeInfo_Annotation_Semantic_NONE = 0,
  GeneratedCodeInfo_Annotation_Semantic_SET = 1,
  GeneratedCodeInfo_Annotation_Semantic_ALIAS = 2,
};

PROTOBUF_EXPORT bool GeneratedCodeInfo_Annotation_Semantic_IsValid(int value);
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation_Semantic_Semantic_MIN = static_cast<GeneratedCodeInfo_Annotation_Semantic>(0);
constexpr GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation_Semantic_Semantic_MAX = static_cast<GeneratedCodeInfo_Annotation_Semantic>(2);
constexpr int GeneratedCodeInfo_Annotation_Semantic_Semantic_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
GeneratedCodeInfo_Annotation_Semantic_descriptor();
template <typename T>
const std::string& GeneratedCodeInfo_Annotation_Semantic_Name(T value) {
  static_assert(std::is_same<T, GeneratedCodeInfo_Annotation_Semantic>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to Semantic_Name().");
  return GeneratedCodeInfo_Annotation_Semantic_Name(static_cast<GeneratedCodeInfo_Annotation_Semantic>(value));
}
template <>
inline const std::string& GeneratedCodeInfo_Annotation_Semantic_Name(GeneratedCodeInfo_Annotation_Semantic value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<GeneratedCodeInfo_Annotation_Semantic_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool GeneratedCodeInfo_Annotation_Semantic_Parse(absl::string_view name, GeneratedCodeInfo_Annotation_Semantic* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<GeneratedCodeInfo_Annotation_Semantic>(
      GeneratedCodeInfo_Annotation_Semantic_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 ::absl::string_view 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 ::absl::string_view 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,
    kEditionFieldNumber = 13,
    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 string edition = 13;
  bool has_edition() const;
  private:
  bool _internal_has_edition() const;
  public:
  void clear_edition();
  const std::string& edition() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_edition(ArgT0&& arg0, ArgT... args);
  std::string* mutable_edition();
  PROTOBUF_NODISCARD std::string* release_edition();
  void set_allocated_edition(std::string* edition);
  private:
  const std::string& _internal_edition() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_edition(const std::string& value);
  std::string* _internal_mutable_edition();
  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::internal::ArenaStringPtr edition_;
    ::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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ----------------------------------------------------

  using Type = FieldDescriptorProto_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 value) {
    return FieldDescriptorProto_Type_Name(value);
  }
  static inline bool Type_Parse(absl::string_view name, Type* value) {
    return FieldDescriptorProto_Type_Parse(name, value);
  }

  using Label = FieldDescriptorProto_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 value) {
    return FieldDescriptorProto_Label_Name(value);
  }
  static inline bool Label_Parse(absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ----------------------------------------------------

  using OptimizeMode = FileOptions_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 value) {
    return FileOptions_OptimizeMode_Name(value);
  }
  static inline bool OptimizeMode_Parse(absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ----------------------------------------------------

  using CType = FieldOptions_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 value) {
    return FieldOptions_CType_Name(value);
  }
  static inline bool CType_Parse(absl::string_view name, CType* value) {
    return FieldOptions_CType_Parse(name, value);
  }

  using JSType = FieldOptions_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 value) {
    return FieldOptions_JSType_Name(value);
  }
  static inline bool JSType_Parse(absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ----------------------------------------------------

  using IdempotencyLevel = MethodOptions_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 value) {
    return MethodOptions_IdempotencyLevel_Name(value);
  }
  static inline bool IdempotencyLevel_Parse(absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::absl::string_view 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 ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _path_cached_byte_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::int32_t > span_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _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 ::absl::string_view 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 ::absl::string_view 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 ----------------------------------------------------

  using Semantic = GeneratedCodeInfo_Annotation_Semantic;
  static constexpr Semantic NONE = GeneratedCodeInfo_Annotation_Semantic_NONE;
  static constexpr Semantic SET = GeneratedCodeInfo_Annotation_Semantic_SET;
  static constexpr Semantic ALIAS = GeneratedCodeInfo_Annotation_Semantic_ALIAS;
  static inline bool Semantic_IsValid(int value) {
    return GeneratedCodeInfo_Annotation_Semantic_IsValid(value);
  }
  static constexpr Semantic Semantic_MIN = GeneratedCodeInfo_Annotation_Semantic_Semantic_MIN;
  static constexpr Semantic Semantic_MAX = GeneratedCodeInfo_Annotation_Semantic_Semantic_MAX;
  static constexpr int Semantic_ARRAYSIZE = GeneratedCodeInfo_Annotation_Semantic_Semantic_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Semantic_descriptor() {
    return GeneratedCodeInfo_Annotation_Semantic_descriptor();
  }
  template <typename T>
  static inline const std::string& Semantic_Name(T value) {
    return GeneratedCodeInfo_Annotation_Semantic_Name(value);
  }
  static inline bool Semantic_Parse(absl::string_view name, Semantic* value) {
    return GeneratedCodeInfo_Annotation_Semantic_Parse(name, value);
  }

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

  enum : int {
    kPathFieldNumber = 1,
    kSourceFileFieldNumber = 2,
    kBeginFieldNumber = 3,
    kEndFieldNumber = 4,
    kSemanticFieldNumber = 5,
  };
  // 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:

  // optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
  bool has_semantic() const;
  private:
  bool _internal_has_semantic() const;
  public:
  void clear_semantic();
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic semantic() const;
  void set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value);
  private:
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic _internal_semantic() const;
  void _internal_set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic 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 ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _path_cached_byte_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr source_file_;
    ::int32_t begin_;
    ::int32_t end_;
    int semantic_;
  };
  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 ::absl::string_view 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
  _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
  _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] & 0x00000010u) != 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] &= ~0x00000010u;
}
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] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options() {
  _impl_._has_bits_[0] &= ~0x00000010u;
  ::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] &= ~0x00000010u;
  ::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] |= 0x00000010u;
  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] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _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] & 0x00000020u) != 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] &= ~0x00000020u;
}
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] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  // @@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] &= ~0x00000020u;
  ::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] &= ~0x00000020u;
  ::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] |= 0x00000020u;
  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] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  _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
  _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)
}

// optional string edition = 13;
inline bool FileDescriptorProto::_internal_has_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool FileDescriptorProto::has_edition() const {
  return _internal_has_edition();
}
inline void FileDescriptorProto::clear_edition() {
  _impl_.edition_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const std::string& FileDescriptorProto::edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.edition)
  return _internal_edition();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void FileDescriptorProto::set_edition(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000008u;
 _impl_.edition_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.edition)
}
inline std::string* FileDescriptorProto::mutable_edition() {
  std::string* _s = _internal_mutable_edition();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.edition)
  return _s;
}
inline const std::string& FileDescriptorProto::_internal_edition() const {
  return _impl_.edition_.Get();
}
inline void FileDescriptorProto::_internal_set_edition(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.edition_.Set(value, GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::_internal_mutable_edition() {
  _impl_._has_bits_[0] |= 0x00000008u;
  return _impl_.edition_.Mutable(GetArenaForAllocation());
}
inline std::string* FileDescriptorProto::release_edition() {
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.edition)
  if (!_internal_has_edition()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000008u;
  auto* p = _impl_.edition_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.edition_.Set("", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void FileDescriptorProto::set_allocated_edition(std::string* edition) {
  if (edition != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.edition_.SetAllocated(edition, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.edition_.IsDefault()) {
    _impl_.edition_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.edition)
}

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

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

// optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5;
inline bool GeneratedCodeInfo_Annotation::_internal_has_semantic() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool GeneratedCodeInfo_Annotation::has_semantic() const {
  return _internal_has_semantic();
}
inline void GeneratedCodeInfo_Annotation::clear_semantic() {
  _impl_.semantic_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::_internal_semantic() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic >(_impl_.semantic_);
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::semantic() const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.semantic)
  return _internal_semantic();
}
inline void GeneratedCodeInfo_Annotation::_internal_set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value) {
  assert(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic_IsValid(value));
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.semantic_ = value;
}
inline void GeneratedCodeInfo_Annotation::set_semantic(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic value) {
  _internal_set_semantic(value);
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.semantic)
}

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

// 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();
}
template <>
struct is_proto_enum<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic>() {
  return ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation_Semantic_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
