// 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 < 4022000
#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 4022005 < 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 FieldOptions_OptionRetention : int {
  FieldOptions_OptionRetention_RETENTION_UNKNOWN = 0,
  FieldOptions_OptionRetention_RETENTION_RUNTIME = 1,
  FieldOptions_OptionRetention_RETENTION_SOURCE = 2,
};

PROTOBUF_EXPORT bool FieldOptions_OptionRetention_IsValid(int value);
constexpr FieldOptions_OptionRetention FieldOptions_OptionRetention_OptionRetention_MIN = static_cast<FieldOptions_OptionRetention>(0);
constexpr FieldOptions_OptionRetention FieldOptions_OptionRetention_OptionRetention_MAX = static_cast<FieldOptions_OptionRetention>(2);
constexpr int FieldOptions_OptionRetention_OptionRetention_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FieldOptions_OptionRetention_descriptor();
template <typename T>
const std::string& FieldOptions_OptionRetention_Name(T value) {
  static_assert(std::is_same<T, FieldOptions_OptionRetention>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to OptionRetention_Name().");
  return FieldOptions_OptionRetention_Name(static_cast<FieldOptions_OptionRetention>(value));
}
template <>
inline const std::string& FieldOptions_OptionRetention_Name(FieldOptions_OptionRetention value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FieldOptions_OptionRetention_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FieldOptions_OptionRetention_Parse(absl::string_view name, FieldOptions_OptionRetention* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_OptionRetention>(
      FieldOptions_OptionRetention_descriptor(), name, value);
}
enum FieldOptions_OptionTargetType : int {
  FieldOptions_OptionTargetType_TARGET_TYPE_UNKNOWN = 0,
  FieldOptions_OptionTargetType_TARGET_TYPE_FILE = 1,
  FieldOptions_OptionTargetType_TARGET_TYPE_EXTENSION_RANGE = 2,
  FieldOptions_OptionTargetType_TARGET_TYPE_MESSAGE = 3,
  FieldOptions_OptionTargetType_TARGET_TYPE_FIELD = 4,
  FieldOptions_OptionTargetType_TARGET_TYPE_ONEOF = 5,
  FieldOptions_OptionTargetType_TARGET_TYPE_ENUM = 6,
  FieldOptions_OptionTargetType_TARGET_TYPE_ENUM_ENTRY = 7,
  FieldOptions_OptionTargetType_TARGET_TYPE_SERVICE = 8,
  FieldOptions_OptionTargetType_TARGET_TYPE_METHOD = 9,
};

PROTOBUF_EXPORT bool FieldOptions_OptionTargetType_IsValid(int value);
constexpr FieldOptions_OptionTargetType FieldOptions_OptionTargetType_OptionTargetType_MIN = static_cast<FieldOptions_OptionTargetType>(0);
constexpr FieldOptions_OptionTargetType FieldOptions_OptionTargetType_OptionTargetType_MAX = static_cast<FieldOptions_OptionTargetType>(9);
constexpr int FieldOptions_OptionTargetType_OptionTargetType_ARRAYSIZE = 9 + 1;
PROTOBUF_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
FieldOptions_OptionTargetType_descriptor();
template <typename T>
const std::string& FieldOptions_OptionTargetType_Name(T value) {
  static_assert(std::is_same<T, FieldOptions_OptionTargetType>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to OptionTargetType_Name().");
  return FieldOptions_OptionTargetType_Name(static_cast<FieldOptions_OptionTargetType>(value));
}
template <>
inline const std::string& FieldOptions_OptionTargetType_Name(FieldOptions_OptionTargetType value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<FieldOptions_OptionTargetType_descriptor,
                                                 0, 9>(
      static_cast<int>(value));
}
inline bool FieldOptions_OptionTargetType_Parse(absl::string_view name, FieldOptions_OptionTargetType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<FieldOptions_OptionTargetType>(
      FieldOptions_OptionTargetType_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;
    ABSL_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);
  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);
  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;
    ABSL_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);
  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);
  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, std::size_t size);
  void set_dependency(int index, absl::string_view value);
  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, std::size_t size);
  void add_dependency(absl::string_view value);
  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() ;
  ::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();

  private:
  ::int32_t _internal_public_dependency(int index) const;
  void _internal_add_public_dependency(::int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& _internal_public_dependency() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* _internal_mutable_public_dependency();

  public:
  // repeated int32 weak_dependency = 11;
  int weak_dependency_size() const;
  private:
  int _internal_weak_dependency_size() const;

  public:
  void clear_weak_dependency() ;
  ::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();

  private:
  ::int32_t _internal_weak_dependency(int index) const;
  void _internal_add_weak_dependency(::int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& _internal_weak_dependency() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* _internal_mutable_weak_dependency();

  public:
  // optional string name = 1;
  bool has_name() const;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  void clear_package() ;
  const std::string& package() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_package(Arg_&& arg, Args_... args);
  std::string* mutable_package();
  PROTOBUF_NODISCARD std::string* release_package();
  void set_allocated_package(std::string* ptr);

  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;
  void clear_syntax() ;
  const std::string& syntax() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_syntax(Arg_&& arg, Args_... args);
  std::string* mutable_syntax();
  PROTOBUF_NODISCARD std::string* release_syntax();
  void set_allocated_syntax(std::string* ptr);

  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;
  void clear_edition() ;
  const std::string& edition() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_edition(Arg_&& arg, Args_... args);
  std::string* mutable_edition();
  PROTOBUF_NODISCARD std::string* release_edition();
  void set_allocated_edition(std::string* ptr);

  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;
  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;
  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;
    ABSL_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);
  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);
  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;
  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;
  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;
  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;
    ABSL_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);
  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);
  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;
  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;
  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;
    ABSL_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);
  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);
  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, std::size_t size);
  void set_reserved_name(int index, absl::string_view value);
  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, std::size_t size);
  void add_reserved_name(absl::string_view value);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  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;
    ABSL_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);
  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);
  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;
    ABSL_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);
  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);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  void clear_extendee() ;
  const std::string& extendee() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_extendee(Arg_&& arg, Args_... args);
  std::string* mutable_extendee();
  PROTOBUF_NODISCARD std::string* release_extendee();
  void set_allocated_extendee(std::string* ptr);

  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;
  void clear_type_name() ;
  const std::string& type_name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_type_name(Arg_&& arg, Args_... args);
  std::string* mutable_type_name();
  PROTOBUF_NODISCARD std::string* release_type_name();
  void set_allocated_type_name(std::string* ptr);

  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;
  void clear_default_value() ;
  const std::string& default_value() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_default_value(Arg_&& arg, Args_... args);
  std::string* mutable_default_value();
  PROTOBUF_NODISCARD std::string* release_default_value();
  void set_allocated_default_value(std::string* ptr);

  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;
  void clear_json_name() ;
  const std::string& json_name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_json_name(Arg_&& arg, Args_... args);
  std::string* mutable_json_name();
  PROTOBUF_NODISCARD std::string* release_json_name();
  void set_allocated_json_name(std::string* ptr);

  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;
  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;
  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;
  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;
  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;
  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  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;
    ABSL_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);
  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);
  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;
  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;
  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;
    ABSL_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);
  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);
  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, std::size_t size);
  void set_reserved_name(int index, absl::string_view value);
  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, std::size_t size);
  void add_reserved_name(absl::string_view value);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_name() ;
  const std::string& name() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* ptr);

  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;
  void clear_input_type() ;
  const std::string& input_type() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_input_type(Arg_&& arg, Args_... args);
  std::string* mutable_input_type();
  PROTOBUF_NODISCARD std::string* release_input_type();
  void set_allocated_input_type(std::string* ptr);

  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;
  void clear_output_type() ;
  const std::string& output_type() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_output_type(Arg_&& arg, Args_... args);
  std::string* mutable_output_type();
  PROTOBUF_NODISCARD std::string* release_output_type();
  void set_allocated_output_type(std::string* ptr);

  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;
  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;
  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_java_package() ;
  const std::string& java_package() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_java_package(Arg_&& arg, Args_... args);
  std::string* mutable_java_package();
  PROTOBUF_NODISCARD std::string* release_java_package();
  void set_allocated_java_package(std::string* ptr);

  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;
  void clear_java_outer_classname() ;
  const std::string& java_outer_classname() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_java_outer_classname(Arg_&& arg, Args_... args);
  std::string* mutable_java_outer_classname();
  PROTOBUF_NODISCARD std::string* release_java_outer_classname();
  void set_allocated_java_outer_classname(std::string* ptr);

  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;
  void clear_go_package() ;
  const std::string& go_package() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_go_package(Arg_&& arg, Args_... args);
  std::string* mutable_go_package();
  PROTOBUF_NODISCARD std::string* release_go_package();
  void set_allocated_go_package(std::string* ptr);

  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;
  void clear_objc_class_prefix() ;
  const std::string& objc_class_prefix() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_objc_class_prefix(Arg_&& arg, Args_... args);
  std::string* mutable_objc_class_prefix();
  PROTOBUF_NODISCARD std::string* release_objc_class_prefix();
  void set_allocated_objc_class_prefix(std::string* ptr);

  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;
  void clear_csharp_namespace() ;
  const std::string& csharp_namespace() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_csharp_namespace(Arg_&& arg, Args_... args);
  std::string* mutable_csharp_namespace();
  PROTOBUF_NODISCARD std::string* release_csharp_namespace();
  void set_allocated_csharp_namespace(std::string* ptr);

  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;
  void clear_swift_prefix() ;
  const std::string& swift_prefix() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_swift_prefix(Arg_&& arg, Args_... args);
  std::string* mutable_swift_prefix();
  PROTOBUF_NODISCARD std::string* release_swift_prefix();
  void set_allocated_swift_prefix(std::string* ptr);

  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;
  void clear_php_class_prefix() ;
  const std::string& php_class_prefix() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_php_class_prefix(Arg_&& arg, Args_... args);
  std::string* mutable_php_class_prefix();
  PROTOBUF_NODISCARD std::string* release_php_class_prefix();
  void set_allocated_php_class_prefix(std::string* ptr);

  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;
  void clear_php_namespace() ;
  const std::string& php_namespace() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_php_namespace(Arg_&& arg, Args_... args);
  std::string* mutable_php_namespace();
  PROTOBUF_NODISCARD std::string* release_php_namespace();
  void set_allocated_php_namespace(std::string* ptr);

  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;
  void clear_php_metadata_namespace() ;
  const std::string& php_metadata_namespace() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_php_metadata_namespace(Arg_&& arg, Args_... args);
  std::string* mutable_php_metadata_namespace();
  PROTOBUF_NODISCARD std::string* release_php_metadata_namespace();
  void set_allocated_php_metadata_namespace(std::string* ptr);

  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;
  void clear_ruby_package() ;
  const std::string& ruby_package() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_ruby_package(Arg_&& arg, Args_... args);
  std::string* mutable_ruby_package();
  PROTOBUF_NODISCARD std::string* release_ruby_package();
  void set_allocated_ruby_package(std::string* ptr);

  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;
  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;
  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;
  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;
  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;
  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;
  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;
  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;
  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;
  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;
  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;
    ABSL_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);
  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);
  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,
    kDeprecatedLegacyJsonFieldConflictsFieldNumber = 11,
  };
  // 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;
  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;
  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;
  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;
  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:
  // optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true];
  PROTOBUF_DEPRECATED  bool has_deprecated_legacy_json_field_conflicts() const;
  PROTOBUF_DEPRECATED  void clear_deprecated_legacy_json_field_conflicts() ;
  PROTOBUF_DEPRECATED bool deprecated_legacy_json_field_conflicts() const;
  PROTOBUF_DEPRECATED void set_deprecated_legacy_json_field_conflicts(bool value);

  private:
  bool _internal_deprecated_legacy_json_field_conflicts() const;
  void _internal_set_deprecated_legacy_json_field_conflicts(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_;
    bool deprecated_legacy_json_field_conflicts_;
  };
  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;
    ABSL_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);
  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);
  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);
  }

  using OptionRetention = FieldOptions_OptionRetention;
  static constexpr OptionRetention RETENTION_UNKNOWN = FieldOptions_OptionRetention_RETENTION_UNKNOWN;
  static constexpr OptionRetention RETENTION_RUNTIME = FieldOptions_OptionRetention_RETENTION_RUNTIME;
  static constexpr OptionRetention RETENTION_SOURCE = FieldOptions_OptionRetention_RETENTION_SOURCE;
  static inline bool OptionRetention_IsValid(int value) {
    return FieldOptions_OptionRetention_IsValid(value);
  }
  static constexpr OptionRetention OptionRetention_MIN = FieldOptions_OptionRetention_OptionRetention_MIN;
  static constexpr OptionRetention OptionRetention_MAX = FieldOptions_OptionRetention_OptionRetention_MAX;
  static constexpr int OptionRetention_ARRAYSIZE = FieldOptions_OptionRetention_OptionRetention_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* OptionRetention_descriptor() {
    return FieldOptions_OptionRetention_descriptor();
  }
  template <typename T>
  static inline const std::string& OptionRetention_Name(T value) {
    return FieldOptions_OptionRetention_Name(value);
  }
  static inline bool OptionRetention_Parse(absl::string_view name, OptionRetention* value) {
    return FieldOptions_OptionRetention_Parse(name, value);
  }

  using OptionTargetType = FieldOptions_OptionTargetType;
  static constexpr OptionTargetType TARGET_TYPE_UNKNOWN = FieldOptions_OptionTargetType_TARGET_TYPE_UNKNOWN;
  static constexpr OptionTargetType TARGET_TYPE_FILE = FieldOptions_OptionTargetType_TARGET_TYPE_FILE;
  static constexpr OptionTargetType TARGET_TYPE_EXTENSION_RANGE = FieldOptions_OptionTargetType_TARGET_TYPE_EXTENSION_RANGE;
  static constexpr OptionTargetType TARGET_TYPE_MESSAGE = FieldOptions_OptionTargetType_TARGET_TYPE_MESSAGE;
  static constexpr OptionTargetType TARGET_TYPE_FIELD = FieldOptions_OptionTargetType_TARGET_TYPE_FIELD;
  static constexpr OptionTargetType TARGET_TYPE_ONEOF = FieldOptions_OptionTargetType_TARGET_TYPE_ONEOF;
  static constexpr OptionTargetType TARGET_TYPE_ENUM = FieldOptions_OptionTargetType_TARGET_TYPE_ENUM;
  static constexpr OptionTargetType TARGET_TYPE_ENUM_ENTRY = FieldOptions_OptionTargetType_TARGET_TYPE_ENUM_ENTRY;
  static constexpr OptionTargetType TARGET_TYPE_SERVICE = FieldOptions_OptionTargetType_TARGET_TYPE_SERVICE;
  static constexpr OptionTargetType TARGET_TYPE_METHOD = FieldOptions_OptionTargetType_TARGET_TYPE_METHOD;
  static inline bool OptionTargetType_IsValid(int value) {
    return FieldOptions_OptionTargetType_IsValid(value);
  }
  static constexpr OptionTargetType OptionTargetType_MIN = FieldOptions_OptionTargetType_OptionTargetType_MIN;
  static constexpr OptionTargetType OptionTargetType_MAX = FieldOptions_OptionTargetType_OptionTargetType_MAX;
  static constexpr int OptionTargetType_ARRAYSIZE = FieldOptions_OptionTargetType_OptionTargetType_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* OptionTargetType_descriptor() {
    return FieldOptions_OptionTargetType_descriptor();
  }
  template <typename T>
  static inline const std::string& OptionTargetType_Name(T value) {
    return FieldOptions_OptionTargetType_Name(value);
  }
  static inline bool OptionTargetType_Parse(absl::string_view name, OptionTargetType* value) {
    return FieldOptions_OptionTargetType_Parse(name, value);
  }

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

  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kCtypeFieldNumber = 1,
    kJstypeFieldNumber = 6,
    kPackedFieldNumber = 2,
    kLazyFieldNumber = 5,
    kUnverifiedLazyFieldNumber = 15,
    kDeprecatedFieldNumber = 3,
    kWeakFieldNumber = 10,
    kDebugRedactFieldNumber = 16,
    kRetentionFieldNumber = 17,
    kTargetFieldNumber = 18,
  };
  // 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;
  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;
  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;
  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;
  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;
  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;
  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;
  void clear_weak() ;
  bool weak() const;
  void set_weak(bool value);

  private:
  bool _internal_weak() const;
  void _internal_set_weak(bool value);

  public:
  // optional bool debug_redact = 16 [default = false];
  bool has_debug_redact() const;
  void clear_debug_redact() ;
  bool debug_redact() const;
  void set_debug_redact(bool value);

  private:
  bool _internal_debug_redact() const;
  void _internal_set_debug_redact(bool value);

  public:
  // optional .google.protobuf.FieldOptions.OptionRetention retention = 17;
  bool has_retention() const;
  void clear_retention() ;
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention retention() const;
  void set_retention(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention value);

  private:
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention _internal_retention() const;
  void _internal_set_retention(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention value);

  public:
  // optional .google.protobuf.FieldOptions.OptionTargetType target = 18;
  bool has_target() const;
  void clear_target() ;
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType target() const;
  void set_target(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType value);

  private:
  ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType _internal_target() const;
  void _internal_set_target(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType 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_;
    bool debug_redact_;
    int retention_;
    int target_;
  };
  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;
    ABSL_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);
  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);
  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;
    ABSL_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);
  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);
  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,
    kDeprecatedLegacyJsonFieldConflictsFieldNumber = 6,
  };
  // 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;
  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;
  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 deprecated_legacy_json_field_conflicts = 6 [deprecated = true];
  PROTOBUF_DEPRECATED  bool has_deprecated_legacy_json_field_conflicts() const;
  PROTOBUF_DEPRECATED  void clear_deprecated_legacy_json_field_conflicts() ;
  PROTOBUF_DEPRECATED bool deprecated_legacy_json_field_conflicts() const;
  PROTOBUF_DEPRECATED void set_deprecated_legacy_json_field_conflicts(bool value);

  private:
  bool _internal_deprecated_legacy_json_field_conflicts() const;
  void _internal_set_deprecated_legacy_json_field_conflicts(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_;
    bool deprecated_legacy_json_field_conflicts_;
  };
  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;
    ABSL_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);
  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);
  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;
  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;
    ABSL_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);
  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);
  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;
  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;
    ABSL_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);
  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);
  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;
  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_name_part() ;
  const std::string& name_part() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_name_part(Arg_&& arg, Args_... args);
  std::string* mutable_name_part();
  PROTOBUF_NODISCARD std::string* release_name_part();
  void set_allocated_name_part(std::string* ptr);

  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;
  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;
    ABSL_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);
  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);
  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;
  void clear_identifier_value() ;
  const std::string& identifier_value() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_identifier_value(Arg_&& arg, Args_... args);
  std::string* mutable_identifier_value();
  PROTOBUF_NODISCARD std::string* release_identifier_value();
  void set_allocated_identifier_value(std::string* ptr);

  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;
  void clear_string_value() ;
  const std::string& string_value() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_string_value(Arg_&& arg, Args_... args);
  std::string* mutable_string_value();
  PROTOBUF_NODISCARD std::string* release_string_value();
  void set_allocated_string_value(std::string* ptr);

  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;
  void clear_aggregate_value() ;
  const std::string& aggregate_value() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_aggregate_value(Arg_&& arg, Args_... args);
  std::string* mutable_aggregate_value();
  PROTOBUF_NODISCARD std::string* release_aggregate_value();
  void set_allocated_aggregate_value(std::string* ptr);

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

  private:
  ::int32_t _internal_path(int index) const;
  void _internal_add_path(::int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& _internal_path() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* _internal_mutable_path();

  public:
  // repeated int32 span = 2 [packed = true];
  int span_size() const;
  private:
  int _internal_span_size() const;

  public:
  void clear_span() ;
  ::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();

  private:
  ::int32_t _internal_span(int index) const;
  void _internal_add_span(::int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& _internal_span() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* _internal_mutable_span();

  public:
  // 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, std::size_t size);
  void set_leading_detached_comments(int index, absl::string_view value);
  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, std::size_t size);
  void add_leading_detached_comments(absl::string_view value);
  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;
  void clear_leading_comments() ;
  const std::string& leading_comments() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_leading_comments(Arg_&& arg, Args_... args);
  std::string* mutable_leading_comments();
  PROTOBUF_NODISCARD std::string* release_leading_comments();
  void set_allocated_leading_comments(std::string* ptr);

  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;
  void clear_trailing_comments() ;
  const std::string& trailing_comments() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_trailing_comments(Arg_&& arg, Args_... args);
  std::string* mutable_trailing_comments();
  PROTOBUF_NODISCARD std::string* release_trailing_comments();
  void set_allocated_trailing_comments(std::string* ptr);

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

  private:
  ::int32_t _internal_path(int index) const;
  void _internal_add_path(::int32_t value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& _internal_path() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* _internal_mutable_path();

  public:
  // optional string source_file = 2;
  bool has_source_file() const;
  void clear_source_file() ;
  const std::string& source_file() const;




  template <typename Arg_ = const std::string&, typename... Args_>
  void set_source_file(Arg_&& arg, Args_... args);
  std::string* mutable_source_file();
  PROTOBUF_NODISCARD std::string* release_source_file();
  void set_allocated_source_file(std::string* ptr);

  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;
  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;
  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;
  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;
    ABSL_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);
  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);
  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::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileDescriptorProto::set_package(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.package_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.package_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.package_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_package(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.package_.SetAllocated(value, 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) {
  ABSL_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,
                              std::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 void FileDescriptorProto::set_dependency(int index, absl::string_view value) {
  _impl_.dependency_.Mutable(index)->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_set_string_piece: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) {
  ABSL_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, std::size_t size) {
  _impl_.dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline void FileDescriptorProto::add_dependency(absl::string_view value) {
  _impl_.dependency_.Add()->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_add_string_piece: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::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::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::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::mutable_public_dependency() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
  return _internal_mutable_public_dependency();
}

inline ::int32_t FileDescriptorProto::_internal_public_dependency(int index) const {
  return _impl_.public_dependency_.Get(index);
}
inline void FileDescriptorProto::_internal_add_public_dependency(::int32_t value) { _impl_.public_dependency_.Add(value); }
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& FileDescriptorProto::_internal_public_dependency() const {
  return _impl_.public_dependency_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* FileDescriptorProto::_internal_mutable_public_dependency() {
  return &_impl_.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::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::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::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::mutable_weak_dependency() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
  return _internal_mutable_weak_dependency();
}

inline ::int32_t FileDescriptorProto::_internal_weak_dependency(int index) const {
  return _impl_.weak_dependency_.Get(index);
}
inline void FileDescriptorProto::_internal_add_weak_dependency(::int32_t value) { _impl_.weak_dependency_.Add(value); }
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& FileDescriptorProto::_internal_weak_dependency() const {
  return _impl_.weak_dependency_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* FileDescriptorProto::_internal_mutable_weak_dependency() {
  return &_impl_.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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_source_code_info() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.source_code_info_ != nullptr);
  return value;
}
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::has_syntax() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileDescriptorProto::set_syntax(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.syntax_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000004u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* released = _impl_.syntax_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.syntax_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_syntax(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.syntax_.SetAllocated(value, 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::has_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileDescriptorProto::set_edition(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.edition_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000008u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000008u;
  auto* released = _impl_.edition_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.edition_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_edition(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.edition_.SetAllocated(value, 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::has_start() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void DescriptorProto_ExtensionRange::clear_start() {
  _impl_.start_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::int32_t DescriptorProto_ExtensionRange::start() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
  return _internal_start();
}
inline void DescriptorProto_ExtensionRange::set_start(::int32_t value) {
  _internal_set_start(value);
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
}
inline ::int32_t DescriptorProto_ExtensionRange::_internal_start() const {
  return _impl_.start_;
}
inline void DescriptorProto_ExtensionRange::_internal_set_start(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.start_ = value;
}

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

// optional .google.protobuf.ExtensionRangeOptions options = 3;
inline bool DescriptorProto_ExtensionRange::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_start() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void DescriptorProto_ReservedRange::clear_start() {
  _impl_.start_ = 0;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline ::int32_t DescriptorProto_ReservedRange::start() const {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start)
  return _internal_start();
}
inline void DescriptorProto_ReservedRange::set_start(::int32_t value) {
  _internal_set_start(value);
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start)
}
inline ::int32_t DescriptorProto_ReservedRange::_internal_start() const {
  return _impl_.start_;
}
inline void DescriptorProto_ReservedRange::_internal_set_start(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.start_ = value;
}

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

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

// DescriptorProto

// optional string name = 1;
inline bool DescriptorProto::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void DescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void DescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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) {
  ABSL_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,
                              std::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 void DescriptorProto::set_reserved_name(int index, absl::string_view value) {
  _impl_.reserved_name_.Mutable(index)->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_set_string_piece: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) {
  ABSL_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, std::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 void DescriptorProto::add_reserved_name(absl::string_view value) {
  _impl_.reserved_name_.Add()->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_add_string_piece: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::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_number() const {
  bool value = (_impl_._has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline void FieldDescriptorProto::clear_number() {
  _impl_.number_ = 0;
  _impl_._has_bits_[0] &= ~0x00000040u;
}
inline ::int32_t FieldDescriptorProto::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
  return _internal_number();
}
inline void FieldDescriptorProto::set_number(::int32_t value) {
  _internal_set_number(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
}
inline ::int32_t FieldDescriptorProto::_internal_number() const {
  return _impl_.number_;
}
inline void FieldDescriptorProto::_internal_set_number(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000040u;
  _impl_.number_ = value;
}

// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
inline bool FieldDescriptorProto::has_label() const {
  bool value = (_impl_._has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline void FieldDescriptorProto::clear_label() {
  _impl_.label_ = 1;
  _impl_._has_bits_[0] &= ~0x00000200u;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
  return _internal_label();
}
inline void FieldDescriptorProto::set_label(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) {
   _internal_set_label(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label>(_impl_.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;
}

// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
inline bool FieldDescriptorProto::has_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000400u) != 0;
  return value;
}
inline void FieldDescriptorProto::clear_type() {
  _impl_.type_ = 1;
  _impl_._has_bits_[0] &= ~0x00000400u;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
  return _internal_type();
}
inline void FieldDescriptorProto::set_type(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) {
   _internal_set_type(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type>(_impl_.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;
}

// optional string type_name = 6;
inline bool FieldDescriptorProto::has_type_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldDescriptorProto::set_type_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.type_name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000004u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* released = _impl_.type_name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.type_name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_type_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.type_name_.SetAllocated(value, 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::has_extendee() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldDescriptorProto::set_extendee(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.extendee_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.extendee_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.extendee_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_extendee(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.extendee_.SetAllocated(value, 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::has_default_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return 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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldDescriptorProto::set_default_value(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.default_value_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000008u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000008u;
  auto* released = _impl_.default_value_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.default_value_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_default_value(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.default_value_.SetAllocated(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::has_oneof_index() const {
  bool value = (_impl_._has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline void FieldDescriptorProto::clear_oneof_index() {
  _impl_.oneof_index_ = 0;
  _impl_._has_bits_[0] &= ~0x00000080u;
}
inline ::int32_t FieldDescriptorProto::oneof_index() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
  return _internal_oneof_index();
}
inline void FieldDescriptorProto::set_oneof_index(::int32_t value) {
  _internal_set_oneof_index(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
}
inline ::int32_t FieldDescriptorProto::_internal_oneof_index() const {
  return _impl_.oneof_index_;
}
inline void FieldDescriptorProto::_internal_set_oneof_index(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000080u;
  _impl_.oneof_index_ = value;
}

// optional string json_name = 10;
inline bool FieldDescriptorProto::has_json_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldDescriptorProto::set_json_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.json_name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000010u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000010u;
  auto* released = _impl_.json_name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.json_name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_json_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.json_name_.SetAllocated(value, 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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_proto3_optional() const {
  bool value = (_impl_._has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline void FieldDescriptorProto::clear_proto3_optional() {
  _impl_.proto3_optional_ = false;
  _impl_._has_bits_[0] &= ~0x00000100u;
}
inline bool FieldDescriptorProto::proto3_optional() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.proto3_optional)
  return _internal_proto3_optional();
}
inline void FieldDescriptorProto::set_proto3_optional(bool value) {
  _internal_set_proto3_optional(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional)
}
inline bool FieldDescriptorProto::_internal_proto3_optional() const {
  return _impl_.proto3_optional_;
}
inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) {
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.proto3_optional_ = value;
}

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

// OneofDescriptorProto

// optional string name = 1;
inline bool OneofDescriptorProto::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void OneofDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void OneofDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_start() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void EnumDescriptorProto_EnumReservedRange::clear_start() {
  _impl_.start_ = 0;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline ::int32_t EnumDescriptorProto_EnumReservedRange::start() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
  return _internal_start();
}
inline void EnumDescriptorProto_EnumReservedRange::set_start(::int32_t value) {
  _internal_set_start(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
}
inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const {
  return _impl_.start_;
}
inline void EnumDescriptorProto_EnumReservedRange::_internal_set_start(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.start_ = value;
}

// optional int32 end = 2;
inline bool EnumDescriptorProto_EnumReservedRange::has_end() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void EnumDescriptorProto_EnumReservedRange::clear_end() {
  _impl_.end_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::int32_t EnumDescriptorProto_EnumReservedRange::end() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
  return _internal_end();
}
inline void EnumDescriptorProto_EnumReservedRange::set_end(::int32_t value) {
  _internal_set_end(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
}
inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const {
  return _impl_.end_;
}
inline void EnumDescriptorProto_EnumReservedRange::_internal_set_end(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.end_ = value;
}

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

// EnumDescriptorProto

// optional string name = 1;
inline bool EnumDescriptorProto::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void EnumDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void EnumDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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) {
  ABSL_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,
                              std::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 void EnumDescriptorProto::set_reserved_name(int index, absl::string_view value) {
  _impl_.reserved_name_.Mutable(index)->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_set_string_piece: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) {
  ABSL_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, std::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 void EnumDescriptorProto::add_reserved_name(absl::string_view value) {
  _impl_.reserved_name_.Add()->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_add_string_piece: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::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void EnumValueDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void EnumValueDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_number() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void EnumValueDescriptorProto::clear_number() {
  _impl_.number_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::int32_t EnumValueDescriptorProto::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
  return _internal_number();
}
inline void EnumValueDescriptorProto::set_number(::int32_t value) {
  _internal_set_number(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
}
inline ::int32_t EnumValueDescriptorProto::_internal_number() const {
  return _impl_.number_;
}
inline void EnumValueDescriptorProto::_internal_set_number(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.number_ = value;
}

// optional .google.protobuf.EnumValueOptions options = 3;
inline bool EnumValueDescriptorProto::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void ServiceDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void ServiceDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void MethodDescriptorProto::set_name(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void MethodDescriptorProto::set_allocated_name(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, 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::has_input_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void MethodDescriptorProto::set_input_type(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.input_type_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.input_type_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.input_type_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void MethodDescriptorProto::set_allocated_input_type(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.input_type_.SetAllocated(value, 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::has_output_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void MethodDescriptorProto::set_output_type(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.output_type_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000004u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* released = _impl_.output_type_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.output_type_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void MethodDescriptorProto::set_allocated_output_type(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.output_type_.SetAllocated(value, 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::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
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::has_client_streaming() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void MethodDescriptorProto::clear_client_streaming() {
  _impl_.client_streaming_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline bool MethodDescriptorProto::client_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming)
  return _internal_client_streaming();
}
inline void MethodDescriptorProto::set_client_streaming(bool value) {
  _internal_set_client_streaming(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming)
}
inline bool MethodDescriptorProto::_internal_client_streaming() const {
  return _impl_.client_streaming_;
}
inline void MethodDescriptorProto::_internal_set_client_streaming(bool value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.client_streaming_ = value;
}

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

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

// FileOptions

// optional string java_package = 1;
inline bool FileOptions::has_java_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_java_package(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.java_package_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.java_package_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.java_package_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_java_package(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.java_package_.SetAllocated(value, 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::has_java_outer_classname() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_java_outer_classname(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.java_outer_classname_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.java_outer_classname_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_java_outer_classname(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.java_outer_classname_.SetAllocated(value, 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::has_java_multiple_files() const {
  bool value = (_impl_._has_bits_[0] & 0x00000400u) != 0;
  return value;
}
inline void FileOptions::clear_java_multiple_files() {
  _impl_.java_multiple_files_ = false;
  _impl_._has_bits_[0] &= ~0x00000400u;
}
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::set_java_multiple_files(bool value) {
  _internal_set_java_multiple_files(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
}
inline bool FileOptions::_internal_java_multiple_files() const {
  return _impl_.java_multiple_files_;
}
inline void FileOptions::_internal_set_java_multiple_files(bool value) {
  _impl_._has_bits_[0] |= 0x00000400u;
  _impl_.java_multiple_files_ = value;
}

// optional bool java_generate_equals_and_hash = 20 [deprecated = true];
inline bool FileOptions::has_java_generate_equals_and_hash() const {
  bool value = (_impl_._has_bits_[0] & 0x00000800u) != 0;
  return value;
}
inline void FileOptions::clear_java_generate_equals_and_hash() {
  _impl_.java_generate_equals_and_hash_ = false;
  _impl_._has_bits_[0] &= ~0x00000800u;
}
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::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)
}
inline bool FileOptions::_internal_java_generate_equals_and_hash() const {
  return _impl_.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;
}

// optional bool java_string_check_utf8 = 27 [default = false];
inline bool FileOptions::has_java_string_check_utf8() const {
  bool value = (_impl_._has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline void FileOptions::clear_java_string_check_utf8() {
  _impl_.java_string_check_utf8_ = false;
  _impl_._has_bits_[0] &= ~0x00001000u;
}
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::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)
}
inline bool FileOptions::_internal_java_string_check_utf8() const {
  return _impl_.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;
}

// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
inline bool FileOptions::has_optimize_for() const {
  bool value = (_impl_._has_bits_[0] & 0x00040000u) != 0;
  return value;
}
inline void FileOptions::clear_optimize_for() {
  _impl_.optimize_for_ = 1;
  _impl_._has_bits_[0] &= ~0x00040000u;
}
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::set_optimize_for(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) {
   _internal_set_optimize_for(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
}
inline ::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode>(_impl_.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;
}

// optional string go_package = 11;
inline bool FileOptions::has_go_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_go_package(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.go_package_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000004u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* released = _impl_.go_package_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.go_package_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_go_package(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.go_package_.SetAllocated(value, 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::has_cc_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline void FileOptions::clear_cc_generic_services() {
  _impl_.cc_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00002000u;
}
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::set_cc_generic_services(bool value) {
  _internal_set_cc_generic_services(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
}
inline bool FileOptions::_internal_cc_generic_services() const {
  return _impl_.cc_generic_services_;
}
inline void FileOptions::_internal_set_cc_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00002000u;
  _impl_.cc_generic_services_ = value;
}

// optional bool java_generic_services = 17 [default = false];
inline bool FileOptions::has_java_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00004000u) != 0;
  return value;
}
inline void FileOptions::clear_java_generic_services() {
  _impl_.java_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00004000u;
}
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::set_java_generic_services(bool value) {
  _internal_set_java_generic_services(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
}
inline bool FileOptions::_internal_java_generic_services() const {
  return _impl_.java_generic_services_;
}
inline void FileOptions::_internal_set_java_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00004000u;
  _impl_.java_generic_services_ = value;
}

// optional bool py_generic_services = 18 [default = false];
inline bool FileOptions::has_py_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00008000u) != 0;
  return value;
}
inline void FileOptions::clear_py_generic_services() {
  _impl_.py_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00008000u;
}
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::set_py_generic_services(bool value) {
  _internal_set_py_generic_services(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
}
inline bool FileOptions::_internal_py_generic_services() const {
  return _impl_.py_generic_services_;
}
inline void FileOptions::_internal_set_py_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00008000u;
  _impl_.py_generic_services_ = value;
}

// optional bool php_generic_services = 42 [default = false];
inline bool FileOptions::has_php_generic_services() const {
  bool value = (_impl_._has_bits_[0] & 0x00010000u) != 0;
  return value;
}
inline void FileOptions::clear_php_generic_services() {
  _impl_.php_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00010000u;
}
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::set_php_generic_services(bool value) {
  _internal_set_php_generic_services(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services)
}
inline bool FileOptions::_internal_php_generic_services() const {
  return _impl_.php_generic_services_;
}
inline void FileOptions::_internal_set_php_generic_services(bool value) {
  _impl_._has_bits_[0] |= 0x00010000u;
  _impl_.php_generic_services_ = value;
}

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

// optional bool cc_enable_arenas = 31 [default = true];
inline bool FileOptions::has_cc_enable_arenas() const {
  bool value = (_impl_._has_bits_[0] & 0x00080000u) != 0;
  return value;
}
inline void FileOptions::clear_cc_enable_arenas() {
  _impl_.cc_enable_arenas_ = true;
  _impl_._has_bits_[0] &= ~0x00080000u;
}
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::set_cc_enable_arenas(bool value) {
  _internal_set_cc_enable_arenas(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
}
inline bool FileOptions::_internal_cc_enable_arenas() const {
  return _impl_.cc_enable_arenas_;
}
inline void FileOptions::_internal_set_cc_enable_arenas(bool value) {
  _impl_._has_bits_[0] |= 0x00080000u;
  _impl_.cc_enable_arenas_ = value;
}

// optional string objc_class_prefix = 36;
inline bool FileOptions::has_objc_class_prefix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_objc_class_prefix(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.objc_class_prefix_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000008u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000008u;
  auto* released = _impl_.objc_class_prefix_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_objc_class_prefix(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.objc_class_prefix_.SetAllocated(value, 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::has_csharp_namespace() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_csharp_namespace(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.csharp_namespace_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000010u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000010u;
  auto* released = _impl_.csharp_namespace_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_csharp_namespace(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.csharp_namespace_.SetAllocated(value, 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::has_swift_prefix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_swift_prefix(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000020u;
  _impl_.swift_prefix_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000020u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000020u;
  auto* released = _impl_.swift_prefix_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.swift_prefix_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_swift_prefix(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  _impl_.swift_prefix_.SetAllocated(value, 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::has_php_class_prefix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000040u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_php_class_prefix(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000040u;
  _impl_.php_class_prefix_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000040u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000040u;
  auto* released = _impl_.php_class_prefix_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_php_class_prefix(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000040u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000040u;
  }
  _impl_.php_class_prefix_.SetAllocated(value, 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::has_php_namespace() const {
  bool value = (_impl_._has_bits_[0] & 0x00000080u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_php_namespace(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000080u;
  _impl_.php_namespace_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000080u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000080u;
  auto* released = _impl_.php_namespace_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.php_namespace_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_php_namespace(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000080u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000080u;
  }
  _impl_.php_namespace_.SetAllocated(value, 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::has_php_metadata_namespace() const {
  bool value = (_impl_._has_bits_[0] & 0x00000100u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_php_metadata_namespace(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.php_metadata_namespace_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000100u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000100u;
  auto* released = _impl_.php_metadata_namespace_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_php_metadata_namespace(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000100u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000100u;
  }
  _impl_.php_metadata_namespace_.SetAllocated(value, 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::has_ruby_package() const {
  bool value = (_impl_._has_bits_[0] & 0x00000200u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FileOptions::set_ruby_package(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000200u;
  _impl_.ruby_package_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000200u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000200u;
  auto* released = _impl_.ruby_package_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.ruby_package_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_ruby_package(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000200u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000200u;
  }
  _impl_.ruby_package_.SetAllocated(value, 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::has_message_set_wire_format() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void MessageOptions::clear_message_set_wire_format() {
  _impl_.message_set_wire_format_ = false;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
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::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)
}
inline bool MessageOptions::_internal_message_set_wire_format() const {
  return _impl_.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;
}

// optional bool no_standard_descriptor_accessor = 2 [default = false];
inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void MessageOptions::clear_no_standard_descriptor_accessor() {
  _impl_.no_standard_descriptor_accessor_ = false;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
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::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)
}
inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const {
  return _impl_.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;
}

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

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

// optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true];
inline bool MessageOptions::has_deprecated_legacy_json_field_conflicts() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void MessageOptions::clear_deprecated_legacy_json_field_conflicts() {
  _impl_.deprecated_legacy_json_field_conflicts_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline bool MessageOptions::deprecated_legacy_json_field_conflicts() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts)
  return _internal_deprecated_legacy_json_field_conflicts();
}
inline void MessageOptions::set_deprecated_legacy_json_field_conflicts(bool value) {
  _internal_set_deprecated_legacy_json_field_conflicts(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts)
}
inline bool MessageOptions::_internal_deprecated_legacy_json_field_conflicts() const {
  return _impl_.deprecated_legacy_json_field_conflicts_;
}
inline void MessageOptions::_internal_set_deprecated_legacy_json_field_conflicts(bool value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.deprecated_legacy_json_field_conflicts_ = value;
}

// 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::has_ctype() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void FieldOptions::clear_ctype() {
  _impl_.ctype_ = 0;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::ctype() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
  return _internal_ctype();
}
inline void FieldOptions::set_ctype(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType value) {
   _internal_set_ctype(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_CType FieldOptions::_internal_ctype() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_CType>(_impl_.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;
}

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

// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
inline bool FieldOptions::has_jstype() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void FieldOptions::clear_jstype() {
  _impl_.jstype_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::jstype() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype)
  return _internal_jstype();
}
inline void FieldOptions::set_jstype(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType value) {
   _internal_set_jstype(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType FieldOptions::_internal_jstype() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType>(_impl_.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;
}

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

// optional bool unverified_lazy = 15 [default = false];
inline bool FieldOptions::has_unverified_lazy() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void FieldOptions::clear_unverified_lazy() {
  _impl_.unverified_lazy_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline bool FieldOptions::unverified_lazy() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.unverified_lazy)
  return _internal_unverified_lazy();
}
inline void FieldOptions::set_unverified_lazy(bool value) {
  _internal_set_unverified_lazy(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.unverified_lazy)
}
inline bool FieldOptions::_internal_unverified_lazy() const {
  return _impl_.unverified_lazy_;
}
inline void FieldOptions::_internal_set_unverified_lazy(bool value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.unverified_lazy_ = value;
}

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

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

// optional bool debug_redact = 16 [default = false];
inline bool FieldOptions::has_debug_redact() const {
  bool value = (_impl_._has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline void FieldOptions::clear_debug_redact() {
  _impl_.debug_redact_ = false;
  _impl_._has_bits_[0] &= ~0x00000080u;
}
inline bool FieldOptions::debug_redact() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.debug_redact)
  return _internal_debug_redact();
}
inline void FieldOptions::set_debug_redact(bool value) {
  _internal_set_debug_redact(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.debug_redact)
}
inline bool FieldOptions::_internal_debug_redact() const {
  return _impl_.debug_redact_;
}
inline void FieldOptions::_internal_set_debug_redact(bool value) {
  _impl_._has_bits_[0] |= 0x00000080u;
  _impl_.debug_redact_ = value;
}

// optional .google.protobuf.FieldOptions.OptionRetention retention = 17;
inline bool FieldOptions::has_retention() const {
  bool value = (_impl_._has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline void FieldOptions::clear_retention() {
  _impl_.retention_ = 0;
  _impl_._has_bits_[0] &= ~0x00000100u;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention FieldOptions::retention() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.retention)
  return _internal_retention();
}
inline void FieldOptions::set_retention(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention value) {
   _internal_set_retention(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.retention)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention FieldOptions::_internal_retention() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention>(_impl_.retention_);
}
inline void FieldOptions::_internal_set_retention(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention value) {
  assert(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionRetention_IsValid(value));
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.retention_ = value;
}

// optional .google.protobuf.FieldOptions.OptionTargetType target = 18;
inline bool FieldOptions::has_target() const {
  bool value = (_impl_._has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline void FieldOptions::clear_target() {
  _impl_.target_ = 0;
  _impl_._has_bits_[0] &= ~0x00000200u;
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType FieldOptions::target() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.target)
  return _internal_target();
}
inline void FieldOptions::set_target(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType value) {
   _internal_set_target(value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.target)
}
inline ::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType FieldOptions::_internal_target() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType>(_impl_.target_);
}
inline void FieldOptions::_internal_set_target(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType value) {
  assert(::PROTOBUF_NAMESPACE_ID::FieldOptions_OptionTargetType_IsValid(value));
  _impl_._has_bits_[0] |= 0x00000200u;
  _impl_.target_ = value;
}

// 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::has_allow_alias() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void EnumOptions::clear_allow_alias() {
  _impl_.allow_alias_ = false;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline bool EnumOptions::allow_alias() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
  return _internal_allow_alias();
}
inline void EnumOptions::set_allow_alias(bool value) {
  _internal_set_allow_alias(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
}
inline bool EnumOptions::_internal_allow_alias() const {
  return _impl_.allow_alias_;
}
inline void EnumOptions::_internal_set_allow_alias(bool value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.allow_alias_ = value;
}

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

// optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true];
inline bool EnumOptions::has_deprecated_legacy_json_field_conflicts() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void EnumOptions::clear_deprecated_legacy_json_field_conflicts() {
  _impl_.deprecated_legacy_json_field_conflicts_ = false;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline bool EnumOptions::deprecated_legacy_json_field_conflicts() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts)
  return _internal_deprecated_legacy_json_field_conflicts();
}
inline void EnumOptions::set_deprecated_legacy_json_field_conflicts(bool value) {
  _internal_set_deprecated_legacy_json_field_conflicts(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts)
}
inline bool EnumOptions::_internal_deprecated_legacy_json_field_conflicts() const {
  return _impl_.deprecated_legacy_json_field_conflicts_;
}
inline void EnumOptions::_internal_set_deprecated_legacy_json_field_conflicts(bool value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.deprecated_legacy_json_field_conflicts_ = value;
}

// 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::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void EnumValueOptions::clear_deprecated() {
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline bool EnumValueOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
  return _internal_deprecated();
}
inline void EnumValueOptions::set_deprecated(bool value) {
  _internal_set_deprecated(value);
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
}
inline bool EnumValueOptions::_internal_deprecated() const {
  return _impl_.deprecated_;
}
inline void EnumValueOptions::_internal_set_deprecated(bool value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.deprecated_ = value;
}

// 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::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void ServiceOptions::clear_deprecated() {
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline bool ServiceOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
  return _internal_deprecated();
}
inline void ServiceOptions::set_deprecated(bool value) {
  _internal_set_deprecated(value);
  // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
}
inline bool ServiceOptions::_internal_deprecated() const {
  return _impl_.deprecated_;
}
inline void ServiceOptions::_internal_set_deprecated(bool value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.deprecated_ = value;
}

// 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::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void MethodOptions::clear_deprecated() {
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline bool MethodOptions::deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
  return _internal_deprecated();
}
inline void MethodOptions::set_deprecated(bool value) {
  _internal_set_deprecated(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
}
inline bool MethodOptions::_internal_deprecated() const {
  return _impl_.deprecated_;
}
inline void MethodOptions::_internal_set_deprecated(bool value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.deprecated_ = value;
}

// optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
inline bool MethodOptions::has_idempotency_level() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void MethodOptions::clear_idempotency_level() {
  _impl_.idempotency_level_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
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::set_idempotency_level(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel value) {
   _internal_set_idempotency_level(value);
  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level)
}
inline ::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const {
  return static_cast<::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel>(_impl_.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;
}

// 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::has_name_part() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void UninterpretedOption_NamePart::set_name_part(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_part_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.name_part_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_part_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_part_.SetAllocated(value, 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::has_is_extension() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void UninterpretedOption_NamePart::clear_is_extension() {
  _impl_.is_extension_ = false;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
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::set_is_extension(bool value) {
  _internal_set_is_extension(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
}
inline bool UninterpretedOption_NamePart::_internal_is_extension() const {
  return _impl_.is_extension_;
}
inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.is_extension_ = value;
}

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

// 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::has_identifier_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return 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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void UninterpretedOption::set_identifier_value(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.identifier_value_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.identifier_value_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.identifier_value_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption::set_allocated_identifier_value(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.identifier_value_.SetAllocated(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::has_positive_int_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline void UninterpretedOption::clear_positive_int_value() {
  _impl_.positive_int_value_ = ::uint64_t{0u};
  _impl_._has_bits_[0] &= ~0x00000008u;
}
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::set_positive_int_value(::uint64_t value) {
  _internal_set_positive_int_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
}
inline ::uint64_t UninterpretedOption::_internal_positive_int_value() const {
  return _impl_.positive_int_value_;
}
inline void UninterpretedOption::_internal_set_positive_int_value(::uint64_t value) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.positive_int_value_ = value;
}

// optional int64 negative_int_value = 5;
inline bool UninterpretedOption::has_negative_int_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void UninterpretedOption::clear_negative_int_value() {
  _impl_.negative_int_value_ = ::int64_t{0};
  _impl_._has_bits_[0] &= ~0x00000010u;
}
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::set_negative_int_value(::int64_t value) {
  _internal_set_negative_int_value(value);
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
}
inline ::int64_t UninterpretedOption::_internal_negative_int_value() const {
  return _impl_.negative_int_value_;
}
inline void UninterpretedOption::_internal_set_negative_int_value(::int64_t value) {
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.negative_int_value_ = value;
}

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

// optional bytes string_value = 7;
inline bool UninterpretedOption::has_string_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return 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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void UninterpretedOption::set_string_value(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.string_value_.SetBytes(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.string_value_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.string_value_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption::set_allocated_string_value(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.string_value_.SetAllocated(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::has_aggregate_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return 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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void UninterpretedOption::set_aggregate_value(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.aggregate_value_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000004u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* released = _impl_.aggregate_value_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.aggregate_value_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption::set_allocated_aggregate_value(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.aggregate_value_.SetAllocated(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::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::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::path() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
  return _internal_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();
}

inline ::int32_t SourceCodeInfo_Location::_internal_path(int index) const {
  return _impl_.path_.Get(index);
}
inline void SourceCodeInfo_Location::_internal_add_path(::int32_t value) { _impl_.path_.Add(value); }
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& SourceCodeInfo_Location::_internal_path() const {
  return _impl_.path_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* SourceCodeInfo_Location::_internal_mutable_path() {
  return &_impl_.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::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::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::span() const {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
  return _internal_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();
}

inline ::int32_t SourceCodeInfo_Location::_internal_span(int index) const {
  return _impl_.span_.Get(index);
}
inline void SourceCodeInfo_Location::_internal_add_span(::int32_t value) { _impl_.span_.Add(value); }
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& SourceCodeInfo_Location::_internal_span() const {
  return _impl_.span_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* SourceCodeInfo_Location::_internal_mutable_span() {
  return &_impl_.span_;
}

// optional string leading_comments = 3;
inline bool SourceCodeInfo_Location::has_leading_comments() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void SourceCodeInfo_Location::set_leading_comments(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.leading_comments_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.leading_comments_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.leading_comments_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.leading_comments_.SetAllocated(value, 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::has_trailing_comments() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void SourceCodeInfo_Location::set_trailing_comments(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.trailing_comments_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.trailing_comments_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.trailing_comments_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.trailing_comments_.SetAllocated(value, 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) {
  ABSL_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,
                              std::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 void SourceCodeInfo_Location::set_leading_detached_comments(int index, absl::string_view value) {
  _impl_.leading_detached_comments_.Mutable(index)->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_set_string_piece: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) {
  ABSL_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, std::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 void SourceCodeInfo_Location::add_leading_detached_comments(absl::string_view value) {
  _impl_.leading_detached_comments_.Add()->assign(value.data(), value.size());
  // @@protoc_insertion_point(field_add_string_piece: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::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::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::path() const {
  // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
  return _internal_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();
}

inline ::int32_t GeneratedCodeInfo_Annotation::_internal_path(int index) const {
  return _impl_.path_.Get(index);
}
inline void GeneratedCodeInfo_Annotation::_internal_add_path(::int32_t value) { _impl_.path_.Add(value); }
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>& GeneratedCodeInfo_Annotation::_internal_path() const {
  return _impl_.path_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<::int32_t>* GeneratedCodeInfo_Annotation::_internal_mutable_path() {
  return &_impl_.path_;
}

// optional string source_file = 2;
inline bool GeneratedCodeInfo_Annotation::has_source_file() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void GeneratedCodeInfo_Annotation::set_source_file(Arg_&& arg,
                                                     Args_... args) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.source_file_.Set(static_cast<Arg_&&>(arg), 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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.source_file_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.source_file_.Set("", GetArenaForAllocation());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* value) {
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.source_file_.SetAllocated(value, 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::has_begin() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void GeneratedCodeInfo_Annotation::clear_begin() {
  _impl_.begin_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::int32_t GeneratedCodeInfo_Annotation::begin() const {
  // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin)
  return _internal_begin();
}
inline void GeneratedCodeInfo_Annotation::set_begin(::int32_t value) {
  _internal_set_begin(value);
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin)
}
inline ::int32_t GeneratedCodeInfo_Annotation::_internal_begin() const {
  return _impl_.begin_;
}
inline void GeneratedCodeInfo_Annotation::_internal_set_begin(::int32_t value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.begin_ = value;
}

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

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

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

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