// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/descriptor.proto
// Protobuf C++ Version: 5.28.0-dev

#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 <utility>

#include "google/protobuf/runtime_version.h"
#if PROTOBUF_VERSION != 5028000
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
#endif
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_tctable_decl.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

namespace google {
namespace protobuf {
namespace internal {
class AnyMetadata;
}  // namespace internal
}  // namespace protobuf
}  // namespace google

// 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 ::google::protobuf::internal::DescriptorTable
    descriptor_table_google_2fprotobuf_2fdescriptor_2eproto;
namespace google {
namespace protobuf {
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 ExtensionRangeOptions_Declaration;
struct ExtensionRangeOptions_DeclarationDefaultTypeInternal;
PROTOBUF_EXPORT extern ExtensionRangeOptions_DeclarationDefaultTypeInternal _ExtensionRangeOptions_Declaration_default_instance_;
class FeatureSet;
struct FeatureSetDefaultTypeInternal;
PROTOBUF_EXPORT extern FeatureSetDefaultTypeInternal _FeatureSet_default_instance_;
class FeatureSetDefaults;
struct FeatureSetDefaultsDefaultTypeInternal;
PROTOBUF_EXPORT extern FeatureSetDefaultsDefaultTypeInternal _FeatureSetDefaults_default_instance_;
class FeatureSetDefaults_FeatureSetEditionDefault;
struct FeatureSetDefaults_FeatureSetEditionDefaultDefaultTypeInternal;
PROTOBUF_EXPORT extern FeatureSetDefaults_FeatureSetEditionDefaultDefaultTypeInternal _FeatureSetDefaults_FeatureSetEditionDefault_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 FieldOptions_EditionDefault;
struct FieldOptions_EditionDefaultDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldOptions_EditionDefaultDefaultTypeInternal _FieldOptions_EditionDefault_default_instance_;
class FieldOptions_FeatureSupport;
struct FieldOptions_FeatureSupportDefaultTypeInternal;
PROTOBUF_EXPORT extern FieldOptions_FeatureSupportDefaultTypeInternal _FieldOptions_FeatureSupport_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_;
namespace internal {
#if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES)
PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstancesSlow();
#endif  // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES)
}  // namespace internal
}  // namespace protobuf
}  // namespace google

namespace google {
namespace protobuf {
enum ExtensionRangeOptions_VerificationState : int {
  ExtensionRangeOptions_VerificationState_DECLARATION = 0,
  ExtensionRangeOptions_VerificationState_UNVERIFIED = 1,
};

PROTOBUF_EXPORT bool ExtensionRangeOptions_VerificationState_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t ExtensionRangeOptions_VerificationState_internal_data_[];
constexpr ExtensionRangeOptions_VerificationState ExtensionRangeOptions_VerificationState_VerificationState_MIN = static_cast<ExtensionRangeOptions_VerificationState>(0);
constexpr ExtensionRangeOptions_VerificationState ExtensionRangeOptions_VerificationState_VerificationState_MAX = static_cast<ExtensionRangeOptions_VerificationState>(1);
constexpr int ExtensionRangeOptions_VerificationState_VerificationState_ARRAYSIZE = 1 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
ExtensionRangeOptions_VerificationState_descriptor();
template <typename T>
const std::string& ExtensionRangeOptions_VerificationState_Name(T value) {
  static_assert(std::is_same<T, ExtensionRangeOptions_VerificationState>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to VerificationState_Name().");
  return ExtensionRangeOptions_VerificationState_Name(static_cast<ExtensionRangeOptions_VerificationState>(value));
}
template <>
inline const std::string& ExtensionRangeOptions_VerificationState_Name(ExtensionRangeOptions_VerificationState value) {
  return ::google::protobuf::internal::NameOfDenseEnum<ExtensionRangeOptions_VerificationState_descriptor,
                                                 0, 1>(
      static_cast<int>(value));
}
inline bool ExtensionRangeOptions_VerificationState_Parse(absl::string_view name, ExtensionRangeOptions_VerificationState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ExtensionRangeOptions_VerificationState>(
      ExtensionRangeOptions_VerificationState_descriptor(), name, value);
}
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);
PROTOBUF_EXPORT extern const uint32_t FieldDescriptorProto_Type_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FieldDescriptorProto_Type_descriptor,
                                                 1, 18>(
      static_cast<int>(value));
}
inline bool FieldDescriptorProto_Type_Parse(absl::string_view name, FieldDescriptorProto_Type* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Type>(
      FieldDescriptorProto_Type_descriptor(), name, value);
}
enum FieldDescriptorProto_Label : int {
  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
  FieldDescriptorProto_Label_LABEL_REPEATED = 3,
  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
};

PROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FieldDescriptorProto_Label_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FieldDescriptorProto_Label_descriptor,
                                                 1, 3>(
      static_cast<int>(value));
}
inline bool FieldDescriptorProto_Label_Parse(absl::string_view name, FieldDescriptorProto_Label* value) {
  return ::google::protobuf::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);
PROTOBUF_EXPORT extern const uint32_t FileOptions_OptimizeMode_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FileOptions_OptimizeMode_descriptor,
                                                 1, 3>(
      static_cast<int>(value));
}
inline bool FileOptions_OptimizeMode_Parse(absl::string_view name, FileOptions_OptimizeMode* value) {
  return ::google::protobuf::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);
PROTOBUF_EXPORT extern const uint32_t FieldOptions_CType_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FieldOptions_CType_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FieldOptions_CType_Parse(absl::string_view name, FieldOptions_CType* value) {
  return ::google::protobuf::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);
PROTOBUF_EXPORT extern const uint32_t FieldOptions_JSType_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FieldOptions_JSType_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FieldOptions_JSType_Parse(absl::string_view name, FieldOptions_JSType* value) {
  return ::google::protobuf::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);
PROTOBUF_EXPORT extern const uint32_t FieldOptions_OptionRetention_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FieldOptions_OptionRetention_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FieldOptions_OptionRetention_Parse(absl::string_view name, FieldOptions_OptionRetention* value) {
  return ::google::protobuf::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);
PROTOBUF_EXPORT extern const uint32_t FieldOptions_OptionTargetType_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<FieldOptions_OptionTargetType_descriptor,
                                                 0, 9>(
      static_cast<int>(value));
}
inline bool FieldOptions_OptionTargetType_Parse(absl::string_view name, FieldOptions_OptionTargetType* value) {
  return ::google::protobuf::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);
PROTOBUF_EXPORT extern const uint32_t MethodOptions_IdempotencyLevel_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<MethodOptions_IdempotencyLevel_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool MethodOptions_IdempotencyLevel_Parse(absl::string_view name, MethodOptions_IdempotencyLevel* value) {
  return ::google::protobuf::internal::ParseNamedEnum<MethodOptions_IdempotencyLevel>(
      MethodOptions_IdempotencyLevel_descriptor(), name, value);
}
enum FeatureSet_FieldPresence : int {
  FeatureSet_FieldPresence_FIELD_PRESENCE_UNKNOWN = 0,
  FeatureSet_FieldPresence_EXPLICIT = 1,
  FeatureSet_FieldPresence_IMPLICIT = 2,
  FeatureSet_FieldPresence_LEGACY_REQUIRED = 3,
};

PROTOBUF_EXPORT bool FeatureSet_FieldPresence_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FeatureSet_FieldPresence_internal_data_[];
constexpr FeatureSet_FieldPresence FeatureSet_FieldPresence_FieldPresence_MIN = static_cast<FeatureSet_FieldPresence>(0);
constexpr FeatureSet_FieldPresence FeatureSet_FieldPresence_FieldPresence_MAX = static_cast<FeatureSet_FieldPresence>(3);
constexpr int FeatureSet_FieldPresence_FieldPresence_ARRAYSIZE = 3 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
FeatureSet_FieldPresence_descriptor();
template <typename T>
const std::string& FeatureSet_FieldPresence_Name(T value) {
  static_assert(std::is_same<T, FeatureSet_FieldPresence>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to FieldPresence_Name().");
  return FeatureSet_FieldPresence_Name(static_cast<FeatureSet_FieldPresence>(value));
}
template <>
inline const std::string& FeatureSet_FieldPresence_Name(FeatureSet_FieldPresence value) {
  return ::google::protobuf::internal::NameOfDenseEnum<FeatureSet_FieldPresence_descriptor,
                                                 0, 3>(
      static_cast<int>(value));
}
inline bool FeatureSet_FieldPresence_Parse(absl::string_view name, FeatureSet_FieldPresence* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FeatureSet_FieldPresence>(
      FeatureSet_FieldPresence_descriptor(), name, value);
}
enum FeatureSet_EnumType : int {
  FeatureSet_EnumType_ENUM_TYPE_UNKNOWN = 0,
  FeatureSet_EnumType_OPEN = 1,
  FeatureSet_EnumType_CLOSED = 2,
};

PROTOBUF_EXPORT bool FeatureSet_EnumType_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FeatureSet_EnumType_internal_data_[];
constexpr FeatureSet_EnumType FeatureSet_EnumType_EnumType_MIN = static_cast<FeatureSet_EnumType>(0);
constexpr FeatureSet_EnumType FeatureSet_EnumType_EnumType_MAX = static_cast<FeatureSet_EnumType>(2);
constexpr int FeatureSet_EnumType_EnumType_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
FeatureSet_EnumType_descriptor();
template <typename T>
const std::string& FeatureSet_EnumType_Name(T value) {
  static_assert(std::is_same<T, FeatureSet_EnumType>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to EnumType_Name().");
  return FeatureSet_EnumType_Name(static_cast<FeatureSet_EnumType>(value));
}
template <>
inline const std::string& FeatureSet_EnumType_Name(FeatureSet_EnumType value) {
  return ::google::protobuf::internal::NameOfDenseEnum<FeatureSet_EnumType_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FeatureSet_EnumType_Parse(absl::string_view name, FeatureSet_EnumType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FeatureSet_EnumType>(
      FeatureSet_EnumType_descriptor(), name, value);
}
enum FeatureSet_RepeatedFieldEncoding : int {
  FeatureSet_RepeatedFieldEncoding_REPEATED_FIELD_ENCODING_UNKNOWN = 0,
  FeatureSet_RepeatedFieldEncoding_PACKED = 1,
  FeatureSet_RepeatedFieldEncoding_EXPANDED = 2,
};

PROTOBUF_EXPORT bool FeatureSet_RepeatedFieldEncoding_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FeatureSet_RepeatedFieldEncoding_internal_data_[];
constexpr FeatureSet_RepeatedFieldEncoding FeatureSet_RepeatedFieldEncoding_RepeatedFieldEncoding_MIN = static_cast<FeatureSet_RepeatedFieldEncoding>(0);
constexpr FeatureSet_RepeatedFieldEncoding FeatureSet_RepeatedFieldEncoding_RepeatedFieldEncoding_MAX = static_cast<FeatureSet_RepeatedFieldEncoding>(2);
constexpr int FeatureSet_RepeatedFieldEncoding_RepeatedFieldEncoding_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
FeatureSet_RepeatedFieldEncoding_descriptor();
template <typename T>
const std::string& FeatureSet_RepeatedFieldEncoding_Name(T value) {
  static_assert(std::is_same<T, FeatureSet_RepeatedFieldEncoding>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to RepeatedFieldEncoding_Name().");
  return FeatureSet_RepeatedFieldEncoding_Name(static_cast<FeatureSet_RepeatedFieldEncoding>(value));
}
template <>
inline const std::string& FeatureSet_RepeatedFieldEncoding_Name(FeatureSet_RepeatedFieldEncoding value) {
  return ::google::protobuf::internal::NameOfDenseEnum<FeatureSet_RepeatedFieldEncoding_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FeatureSet_RepeatedFieldEncoding_Parse(absl::string_view name, FeatureSet_RepeatedFieldEncoding* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FeatureSet_RepeatedFieldEncoding>(
      FeatureSet_RepeatedFieldEncoding_descriptor(), name, value);
}
enum FeatureSet_Utf8Validation : int {
  FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN = 0,
  FeatureSet_Utf8Validation_VERIFY = 2,
  FeatureSet_Utf8Validation_NONE = 3,
};

PROTOBUF_EXPORT bool FeatureSet_Utf8Validation_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FeatureSet_Utf8Validation_internal_data_[];
constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MIN = static_cast<FeatureSet_Utf8Validation>(0);
constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast<FeatureSet_Utf8Validation>(3);
constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 3 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
FeatureSet_Utf8Validation_descriptor();
template <typename T>
const std::string& FeatureSet_Utf8Validation_Name(T value) {
  static_assert(std::is_same<T, FeatureSet_Utf8Validation>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to Utf8Validation_Name().");
  return FeatureSet_Utf8Validation_Name(static_cast<FeatureSet_Utf8Validation>(value));
}
template <>
inline const std::string& FeatureSet_Utf8Validation_Name(FeatureSet_Utf8Validation value) {
  return ::google::protobuf::internal::NameOfDenseEnum<FeatureSet_Utf8Validation_descriptor,
                                                 0, 3>(
      static_cast<int>(value));
}
inline bool FeatureSet_Utf8Validation_Parse(absl::string_view name, FeatureSet_Utf8Validation* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FeatureSet_Utf8Validation>(
      FeatureSet_Utf8Validation_descriptor(), name, value);
}
enum FeatureSet_MessageEncoding : int {
  FeatureSet_MessageEncoding_MESSAGE_ENCODING_UNKNOWN = 0,
  FeatureSet_MessageEncoding_LENGTH_PREFIXED = 1,
  FeatureSet_MessageEncoding_DELIMITED = 2,
};

PROTOBUF_EXPORT bool FeatureSet_MessageEncoding_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FeatureSet_MessageEncoding_internal_data_[];
constexpr FeatureSet_MessageEncoding FeatureSet_MessageEncoding_MessageEncoding_MIN = static_cast<FeatureSet_MessageEncoding>(0);
constexpr FeatureSet_MessageEncoding FeatureSet_MessageEncoding_MessageEncoding_MAX = static_cast<FeatureSet_MessageEncoding>(2);
constexpr int FeatureSet_MessageEncoding_MessageEncoding_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
FeatureSet_MessageEncoding_descriptor();
template <typename T>
const std::string& FeatureSet_MessageEncoding_Name(T value) {
  static_assert(std::is_same<T, FeatureSet_MessageEncoding>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to MessageEncoding_Name().");
  return FeatureSet_MessageEncoding_Name(static_cast<FeatureSet_MessageEncoding>(value));
}
template <>
inline const std::string& FeatureSet_MessageEncoding_Name(FeatureSet_MessageEncoding value) {
  return ::google::protobuf::internal::NameOfDenseEnum<FeatureSet_MessageEncoding_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FeatureSet_MessageEncoding_Parse(absl::string_view name, FeatureSet_MessageEncoding* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FeatureSet_MessageEncoding>(
      FeatureSet_MessageEncoding_descriptor(), name, value);
}
enum FeatureSet_JsonFormat : int {
  FeatureSet_JsonFormat_JSON_FORMAT_UNKNOWN = 0,
  FeatureSet_JsonFormat_ALLOW = 1,
  FeatureSet_JsonFormat_LEGACY_BEST_EFFORT = 2,
};

PROTOBUF_EXPORT bool FeatureSet_JsonFormat_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t FeatureSet_JsonFormat_internal_data_[];
constexpr FeatureSet_JsonFormat FeatureSet_JsonFormat_JsonFormat_MIN = static_cast<FeatureSet_JsonFormat>(0);
constexpr FeatureSet_JsonFormat FeatureSet_JsonFormat_JsonFormat_MAX = static_cast<FeatureSet_JsonFormat>(2);
constexpr int FeatureSet_JsonFormat_JsonFormat_ARRAYSIZE = 2 + 1;
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
FeatureSet_JsonFormat_descriptor();
template <typename T>
const std::string& FeatureSet_JsonFormat_Name(T value) {
  static_assert(std::is_same<T, FeatureSet_JsonFormat>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to JsonFormat_Name().");
  return FeatureSet_JsonFormat_Name(static_cast<FeatureSet_JsonFormat>(value));
}
template <>
inline const std::string& FeatureSet_JsonFormat_Name(FeatureSet_JsonFormat value) {
  return ::google::protobuf::internal::NameOfDenseEnum<FeatureSet_JsonFormat_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool FeatureSet_JsonFormat_Parse(absl::string_view name, FeatureSet_JsonFormat* value) {
  return ::google::protobuf::internal::ParseNamedEnum<FeatureSet_JsonFormat>(
      FeatureSet_JsonFormat_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);
PROTOBUF_EXPORT extern const uint32_t GeneratedCodeInfo_Annotation_Semantic_internal_data_[];
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 ::google::protobuf::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 ::google::protobuf::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 ::google::protobuf::internal::ParseNamedEnum<GeneratedCodeInfo_Annotation_Semantic>(
      GeneratedCodeInfo_Annotation_Semantic_descriptor(), name, value);
}
enum Edition : int {
  EDITION_UNKNOWN = 0,
  EDITION_LEGACY = 900,
  EDITION_PROTO2 = 998,
  EDITION_PROTO3 = 999,
  EDITION_2023 = 1000,
  EDITION_2024 = 1001,
  EDITION_1_TEST_ONLY = 1,
  EDITION_2_TEST_ONLY = 2,
  EDITION_99997_TEST_ONLY = 99997,
  EDITION_99998_TEST_ONLY = 99998,
  EDITION_99999_TEST_ONLY = 99999,
  EDITION_MAX = 2147483647,
};

PROTOBUF_EXPORT bool Edition_IsValid(int value);
PROTOBUF_EXPORT extern const uint32_t Edition_internal_data_[];
constexpr Edition Edition_MIN = static_cast<Edition>(0);
constexpr Edition Edition_MAX = static_cast<Edition>(2147483647);
PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor*
Edition_descriptor();
template <typename T>
const std::string& Edition_Name(T value) {
  static_assert(std::is_same<T, Edition>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to Edition_Name().");
  return ::google::protobuf::internal::NameOfEnum(Edition_descriptor(), value);
}
inline bool Edition_Parse(absl::string_view name, Edition* value) {
  return ::google::protobuf::internal::ParseNamedEnum<Edition>(
      Edition_descriptor(), name, value);
}

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


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

class PROTOBUF_EXPORT UninterpretedOption_NamePart final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ {
 public:
  inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {}
  ~UninterpretedOption_NamePart() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR UninterpretedOption_NamePart(
      ::google::protobuf::internal::ConstantInitialized);

  inline UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) : UninterpretedOption_NamePart(nullptr, from) {}
  inline UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept
      : UninterpretedOption_NamePart(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 24;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(UninterpretedOption_NamePart* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  UninterpretedOption_NamePart* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<UninterpretedOption_NamePart>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const UninterpretedOption_NamePart& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const UninterpretedOption_NamePart& from) { UninterpretedOption_NamePart::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(UninterpretedOption_NamePart* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.UninterpretedOption.NamePart"; }

 protected:
  explicit UninterpretedOption_NamePart(::google::protobuf::Arena* arena);
  UninterpretedOption_NamePart(::google::protobuf::Arena* arena, const UninterpretedOption_NamePart& from);
  UninterpretedOption_NamePart(::google::protobuf::Arena* arena, UninterpretedOption_NamePart&& from) noexcept
      : UninterpretedOption_NamePart(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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* value);

  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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      1, 2, 0,
      62, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_UninterpretedOption_NamePart_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const UninterpretedOption_NamePart& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr name_part_;
    bool is_extension_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT SourceCodeInfo_Location final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ {
 public:
  inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {}
  ~SourceCodeInfo_Location() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR SourceCodeInfo_Location(
      ::google::protobuf::internal::ConstantInitialized);

  inline SourceCodeInfo_Location(const SourceCodeInfo_Location& from) : SourceCodeInfo_Location(nullptr, from) {}
  inline SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept
      : SourceCodeInfo_Location(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 29;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(SourceCodeInfo_Location* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  SourceCodeInfo_Location* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<SourceCodeInfo_Location>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const SourceCodeInfo_Location& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const SourceCodeInfo_Location& from) { SourceCodeInfo_Location::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(SourceCodeInfo_Location* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.SourceCodeInfo.Location"; }

 protected:
  explicit SourceCodeInfo_Location(::google::protobuf::Arena* arena);
  SourceCodeInfo_Location(::google::protobuf::Arena* arena, const SourceCodeInfo_Location& from);
  SourceCodeInfo_Location(::google::protobuf::Arena* arena, SourceCodeInfo_Location&& from) noexcept
      : SourceCodeInfo_Location(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 ::google::protobuf::RepeatedField<::int32_t>& path() const;
  ::google::protobuf::RepeatedField<::int32_t>* mutable_path();

  private:
  const ::google::protobuf::RepeatedField<::int32_t>& _internal_path() const;
  ::google::protobuf::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 ::google::protobuf::RepeatedField<::int32_t>& span() const;
  ::google::protobuf::RepeatedField<::int32_t>* mutable_span();

  private:
  const ::google::protobuf::RepeatedField<::int32_t>& _internal_span() const;
  ::google::protobuf::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);
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_leading_detached_comments(int index, Arg_&& value, Args_... args);
  std::string* add_leading_detached_comments();
  template <typename Arg_ = const std::string&, typename... Args_>
  void add_leading_detached_comments(Arg_&& value, Args_... args);
  const ::google::protobuf::RepeatedPtrField<std::string>& leading_detached_comments() const;
  ::google::protobuf::RepeatedPtrField<std::string>* mutable_leading_detached_comments();

  private:
  const ::google::protobuf::RepeatedPtrField<std::string>& _internal_leading_detached_comments() const;
  ::google::protobuf::RepeatedPtrField<std::string>* _internal_mutable_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* value);

  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* value);

  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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 0,
      106, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_SourceCodeInfo_Location_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const SourceCodeInfo_Location& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedField<::int32_t> path_;
    mutable ::google::protobuf::internal::CachedSize _path_cached_byte_size_;
    ::google::protobuf::RepeatedField<::int32_t> span_;
    mutable ::google::protobuf::internal::CachedSize _span_cached_byte_size_;
    ::google::protobuf::RepeatedPtrField<std::string> leading_detached_comments_;
    ::google::protobuf::internal::ArenaStringPtr leading_comments_;
    ::google::protobuf::internal::ArenaStringPtr trailing_comments_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ {
 public:
  inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {}
  ~GeneratedCodeInfo_Annotation() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation(
      ::google::protobuf::internal::ConstantInitialized);

  inline GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from) : GeneratedCodeInfo_Annotation(nullptr, from) {}
  inline GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept
      : GeneratedCodeInfo_Annotation(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 31;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GeneratedCodeInfo_Annotation* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  GeneratedCodeInfo_Annotation* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<GeneratedCodeInfo_Annotation>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const GeneratedCodeInfo_Annotation& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const GeneratedCodeInfo_Annotation& from) { GeneratedCodeInfo_Annotation::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(GeneratedCodeInfo_Annotation* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.GeneratedCodeInfo.Annotation"; }

 protected:
  explicit GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena);
  GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena, const GeneratedCodeInfo_Annotation& from);
  GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena, GeneratedCodeInfo_Annotation&& from) noexcept
      : GeneratedCodeInfo_Annotation(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 ::google::protobuf::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 ::google::protobuf::RepeatedField<::int32_t>& path() const;
  ::google::protobuf::RepeatedField<::int32_t>* mutable_path();

  private:
  const ::google::protobuf::RepeatedField<::int32_t>& _internal_path() const;
  ::google::protobuf::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* value);

  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() ;
  ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic semantic() const;
  void set_semantic(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic value);

  private:
  ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic _internal_semantic() const;
  void _internal_set_semantic(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 1,
      64, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_GeneratedCodeInfo_Annotation_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const GeneratedCodeInfo_Annotation& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedField<::int32_t> path_;
    mutable ::google::protobuf::internal::CachedSize _path_cached_byte_size_;
    ::google::protobuf::internal::ArenaStringPtr source_file_;
    ::int32_t begin_;
    ::int32_t end_;
    int semantic_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FieldOptions_FeatureSupport final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions.FeatureSupport) */ {
 public:
  inline FieldOptions_FeatureSupport() : FieldOptions_FeatureSupport(nullptr) {}
  ~FieldOptions_FeatureSupport() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FieldOptions_FeatureSupport(
      ::google::protobuf::internal::ConstantInitialized);

  inline FieldOptions_FeatureSupport(const FieldOptions_FeatureSupport& from) : FieldOptions_FeatureSupport(nullptr, from) {}
  inline FieldOptions_FeatureSupport(FieldOptions_FeatureSupport&& from) noexcept
      : FieldOptions_FeatureSupport(nullptr, std::move(from)) {}
  inline FieldOptions_FeatureSupport& operator=(const FieldOptions_FeatureSupport& from) {
    CopyFrom(from);
    return *this;
  }
  inline FieldOptions_FeatureSupport& operator=(FieldOptions_FeatureSupport&& from) noexcept {
    if (this == &from) return *this;
    if (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FieldOptions_FeatureSupport& default_instance() {
    return *internal_default_instance();
  }
  static inline const FieldOptions_FeatureSupport* internal_default_instance() {
    return reinterpret_cast<const FieldOptions_FeatureSupport*>(
        &_FieldOptions_FeatureSupport_default_instance_);
  }
  static constexpr int kIndexInFileMessages = 17;
  friend void swap(FieldOptions_FeatureSupport& a, FieldOptions_FeatureSupport& b) { a.Swap(&b); }
  inline void Swap(FieldOptions_FeatureSupport* other) {
    if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FieldOptions_FeatureSupport* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FieldOptions_FeatureSupport* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FieldOptions_FeatureSupport>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FieldOptions_FeatureSupport& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FieldOptions_FeatureSupport& from) { FieldOptions_FeatureSupport::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FieldOptions_FeatureSupport* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions.FeatureSupport"; }

 protected:
  explicit FieldOptions_FeatureSupport(::google::protobuf::Arena* arena);
  FieldOptions_FeatureSupport(::google::protobuf::Arena* arena, const FieldOptions_FeatureSupport& from);
  FieldOptions_FeatureSupport(::google::protobuf::Arena* arena, FieldOptions_FeatureSupport&& from) noexcept
      : FieldOptions_FeatureSupport(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kDeprecationWarningFieldNumber = 3,
    kEditionIntroducedFieldNumber = 1,
    kEditionDeprecatedFieldNumber = 2,
    kEditionRemovedFieldNumber = 4,
  };
  // optional string deprecation_warning = 3;
  bool has_deprecation_warning() const;
  void clear_deprecation_warning() ;
  const std::string& deprecation_warning() const;
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_deprecation_warning(Arg_&& arg, Args_... args);
  std::string* mutable_deprecation_warning();
  PROTOBUF_NODISCARD std::string* release_deprecation_warning();
  void set_allocated_deprecation_warning(std::string* value);

  private:
  const std::string& _internal_deprecation_warning() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_deprecation_warning(
      const std::string& value);
  std::string* _internal_mutable_deprecation_warning();

  public:
  // optional .google.protobuf.Edition edition_introduced = 1;
  bool has_edition_introduced() const;
  void clear_edition_introduced() ;
  ::google::protobuf::Edition edition_introduced() const;
  void set_edition_introduced(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_edition_introduced() const;
  void _internal_set_edition_introduced(::google::protobuf::Edition value);

  public:
  // optional .google.protobuf.Edition edition_deprecated = 2;
  bool has_edition_deprecated() const;
  void clear_edition_deprecated() ;
  ::google::protobuf::Edition edition_deprecated() const;
  void set_edition_deprecated(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_edition_deprecated() const;
  void _internal_set_edition_deprecated(::google::protobuf::Edition value);

  public:
  // optional .google.protobuf.Edition edition_removed = 4;
  bool has_edition_removed() const;
  void clear_edition_removed() ;
  ::google::protobuf::Edition edition_removed() const;
  void set_edition_removed(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_edition_removed() const;
  void _internal_set_edition_removed(::google::protobuf::Edition value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions.FeatureSupport)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 4, 3,
      71, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FieldOptions_FeatureSupport_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FieldOptions_FeatureSupport& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr deprecation_warning_;
    int edition_introduced_;
    int edition_deprecated_;
    int edition_removed_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FieldOptions_EditionDefault final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions.EditionDefault) */ {
 public:
  inline FieldOptions_EditionDefault() : FieldOptions_EditionDefault(nullptr) {}
  ~FieldOptions_EditionDefault() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FieldOptions_EditionDefault(
      ::google::protobuf::internal::ConstantInitialized);

  inline FieldOptions_EditionDefault(const FieldOptions_EditionDefault& from) : FieldOptions_EditionDefault(nullptr, from) {}
  inline FieldOptions_EditionDefault(FieldOptions_EditionDefault&& from) noexcept
      : FieldOptions_EditionDefault(nullptr, std::move(from)) {}
  inline FieldOptions_EditionDefault& operator=(const FieldOptions_EditionDefault& from) {
    CopyFrom(from);
    return *this;
  }
  inline FieldOptions_EditionDefault& operator=(FieldOptions_EditionDefault&& from) noexcept {
    if (this == &from) return *this;
    if (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FieldOptions_EditionDefault& default_instance() {
    return *internal_default_instance();
  }
  static inline const FieldOptions_EditionDefault* internal_default_instance() {
    return reinterpret_cast<const FieldOptions_EditionDefault*>(
        &_FieldOptions_EditionDefault_default_instance_);
  }
  static constexpr int kIndexInFileMessages = 16;
  friend void swap(FieldOptions_EditionDefault& a, FieldOptions_EditionDefault& b) { a.Swap(&b); }
  inline void Swap(FieldOptions_EditionDefault* other) {
    if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FieldOptions_EditionDefault* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FieldOptions_EditionDefault* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FieldOptions_EditionDefault>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FieldOptions_EditionDefault& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FieldOptions_EditionDefault& from) { FieldOptions_EditionDefault::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FieldOptions_EditionDefault* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions.EditionDefault"; }

 protected:
  explicit FieldOptions_EditionDefault(::google::protobuf::Arena* arena);
  FieldOptions_EditionDefault(::google::protobuf::Arena* arena, const FieldOptions_EditionDefault& from);
  FieldOptions_EditionDefault(::google::protobuf::Arena* arena, FieldOptions_EditionDefault&& from) noexcept
      : FieldOptions_EditionDefault(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kValueFieldNumber = 2,
    kEditionFieldNumber = 3,
  };
  // optional string value = 2;
  bool has_value() const;
  void clear_value() ;
  const std::string& value() const;
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_value(Arg_&& arg, Args_... args);
  std::string* mutable_value();
  PROTOBUF_NODISCARD std::string* release_value();
  void set_allocated_value(std::string* value);

  private:
  const std::string& _internal_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_value(
      const std::string& value);
  std::string* _internal_mutable_value();

  public:
  // optional .google.protobuf.Edition edition = 3;
  bool has_edition() const;
  void clear_edition() ;
  ::google::protobuf::Edition edition() const;
  void set_edition(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_edition() const;
  void _internal_set_edition(::google::protobuf::Edition value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions.EditionDefault)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      1, 2, 1,
      57, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FieldOptions_EditionDefault_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FieldOptions_EditionDefault& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr value_;
    int edition_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FeatureSet final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSet) */ {
 public:
  inline FeatureSet() : FeatureSet(nullptr) {}
  ~FeatureSet() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FeatureSet(
      ::google::protobuf::internal::ConstantInitialized);

  inline FeatureSet(const FeatureSet& from) : FeatureSet(nullptr, from) {}
  inline FeatureSet(FeatureSet&& from) noexcept
      : FeatureSet(nullptr, std::move(from)) {}
  inline FeatureSet& operator=(const FeatureSet& from) {
    CopyFrom(from);
    return *this;
  }
  inline FeatureSet& operator=(FeatureSet&& from) noexcept {
    if (this == &from) return *this;
    if (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FeatureSet& default_instance() {
    return *internal_default_instance();
  }
  static inline const FeatureSet* internal_default_instance() {
    return reinterpret_cast<const FeatureSet*>(
        &_FeatureSet_default_instance_);
  }
  static constexpr int kIndexInFileMessages = 26;
  friend void swap(FeatureSet& a, FeatureSet& b) { a.Swap(&b); }
  inline void Swap(FeatureSet* other) {
    if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FeatureSet* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FeatureSet* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FeatureSet>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FeatureSet& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FeatureSet& from) { FeatureSet::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FeatureSet* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSet"; }

 protected:
  explicit FeatureSet(::google::protobuf::Arena* arena);
  FeatureSet(::google::protobuf::Arena* arena, const FeatureSet& from);
  FeatureSet(::google::protobuf::Arena* arena, FeatureSet&& from) noexcept
      : FeatureSet(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using FieldPresence = FeatureSet_FieldPresence;
  static constexpr FieldPresence FIELD_PRESENCE_UNKNOWN = FeatureSet_FieldPresence_FIELD_PRESENCE_UNKNOWN;
  static constexpr FieldPresence EXPLICIT = FeatureSet_FieldPresence_EXPLICIT;
  static constexpr FieldPresence IMPLICIT = FeatureSet_FieldPresence_IMPLICIT;
  static constexpr FieldPresence LEGACY_REQUIRED = FeatureSet_FieldPresence_LEGACY_REQUIRED;
  static inline bool FieldPresence_IsValid(int value) {
    return FeatureSet_FieldPresence_IsValid(value);
  }
  static constexpr FieldPresence FieldPresence_MIN = FeatureSet_FieldPresence_FieldPresence_MIN;
  static constexpr FieldPresence FieldPresence_MAX = FeatureSet_FieldPresence_FieldPresence_MAX;
  static constexpr int FieldPresence_ARRAYSIZE = FeatureSet_FieldPresence_FieldPresence_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* FieldPresence_descriptor() {
    return FeatureSet_FieldPresence_descriptor();
  }
  template <typename T>
  static inline const std::string& FieldPresence_Name(T value) {
    return FeatureSet_FieldPresence_Name(value);
  }
  static inline bool FieldPresence_Parse(absl::string_view name, FieldPresence* value) {
    return FeatureSet_FieldPresence_Parse(name, value);
  }
  using EnumType = FeatureSet_EnumType;
  static constexpr EnumType ENUM_TYPE_UNKNOWN = FeatureSet_EnumType_ENUM_TYPE_UNKNOWN;
  static constexpr EnumType OPEN = FeatureSet_EnumType_OPEN;
  static constexpr EnumType CLOSED = FeatureSet_EnumType_CLOSED;
  static inline bool EnumType_IsValid(int value) {
    return FeatureSet_EnumType_IsValid(value);
  }
  static constexpr EnumType EnumType_MIN = FeatureSet_EnumType_EnumType_MIN;
  static constexpr EnumType EnumType_MAX = FeatureSet_EnumType_EnumType_MAX;
  static constexpr int EnumType_ARRAYSIZE = FeatureSet_EnumType_EnumType_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* EnumType_descriptor() {
    return FeatureSet_EnumType_descriptor();
  }
  template <typename T>
  static inline const std::string& EnumType_Name(T value) {
    return FeatureSet_EnumType_Name(value);
  }
  static inline bool EnumType_Parse(absl::string_view name, EnumType* value) {
    return FeatureSet_EnumType_Parse(name, value);
  }
  using RepeatedFieldEncoding = FeatureSet_RepeatedFieldEncoding;
  static constexpr RepeatedFieldEncoding REPEATED_FIELD_ENCODING_UNKNOWN = FeatureSet_RepeatedFieldEncoding_REPEATED_FIELD_ENCODING_UNKNOWN;
  static constexpr RepeatedFieldEncoding PACKED = FeatureSet_RepeatedFieldEncoding_PACKED;
  static constexpr RepeatedFieldEncoding EXPANDED = FeatureSet_RepeatedFieldEncoding_EXPANDED;
  static inline bool RepeatedFieldEncoding_IsValid(int value) {
    return FeatureSet_RepeatedFieldEncoding_IsValid(value);
  }
  static constexpr RepeatedFieldEncoding RepeatedFieldEncoding_MIN = FeatureSet_RepeatedFieldEncoding_RepeatedFieldEncoding_MIN;
  static constexpr RepeatedFieldEncoding RepeatedFieldEncoding_MAX = FeatureSet_RepeatedFieldEncoding_RepeatedFieldEncoding_MAX;
  static constexpr int RepeatedFieldEncoding_ARRAYSIZE = FeatureSet_RepeatedFieldEncoding_RepeatedFieldEncoding_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* RepeatedFieldEncoding_descriptor() {
    return FeatureSet_RepeatedFieldEncoding_descriptor();
  }
  template <typename T>
  static inline const std::string& RepeatedFieldEncoding_Name(T value) {
    return FeatureSet_RepeatedFieldEncoding_Name(value);
  }
  static inline bool RepeatedFieldEncoding_Parse(absl::string_view name, RepeatedFieldEncoding* value) {
    return FeatureSet_RepeatedFieldEncoding_Parse(name, value);
  }
  using Utf8Validation = FeatureSet_Utf8Validation;
  static constexpr Utf8Validation UTF8_VALIDATION_UNKNOWN = FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN;
  static constexpr Utf8Validation VERIFY = FeatureSet_Utf8Validation_VERIFY;
  static constexpr Utf8Validation NONE = FeatureSet_Utf8Validation_NONE;
  static inline bool Utf8Validation_IsValid(int value) {
    return FeatureSet_Utf8Validation_IsValid(value);
  }
  static constexpr Utf8Validation Utf8Validation_MIN = FeatureSet_Utf8Validation_Utf8Validation_MIN;
  static constexpr Utf8Validation Utf8Validation_MAX = FeatureSet_Utf8Validation_Utf8Validation_MAX;
  static constexpr int Utf8Validation_ARRAYSIZE = FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* Utf8Validation_descriptor() {
    return FeatureSet_Utf8Validation_descriptor();
  }
  template <typename T>
  static inline const std::string& Utf8Validation_Name(T value) {
    return FeatureSet_Utf8Validation_Name(value);
  }
  static inline bool Utf8Validation_Parse(absl::string_view name, Utf8Validation* value) {
    return FeatureSet_Utf8Validation_Parse(name, value);
  }
  using MessageEncoding = FeatureSet_MessageEncoding;
  static constexpr MessageEncoding MESSAGE_ENCODING_UNKNOWN = FeatureSet_MessageEncoding_MESSAGE_ENCODING_UNKNOWN;
  static constexpr MessageEncoding LENGTH_PREFIXED = FeatureSet_MessageEncoding_LENGTH_PREFIXED;
  static constexpr MessageEncoding DELIMITED = FeatureSet_MessageEncoding_DELIMITED;
  static inline bool MessageEncoding_IsValid(int value) {
    return FeatureSet_MessageEncoding_IsValid(value);
  }
  static constexpr MessageEncoding MessageEncoding_MIN = FeatureSet_MessageEncoding_MessageEncoding_MIN;
  static constexpr MessageEncoding MessageEncoding_MAX = FeatureSet_MessageEncoding_MessageEncoding_MAX;
  static constexpr int MessageEncoding_ARRAYSIZE = FeatureSet_MessageEncoding_MessageEncoding_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* MessageEncoding_descriptor() {
    return FeatureSet_MessageEncoding_descriptor();
  }
  template <typename T>
  static inline const std::string& MessageEncoding_Name(T value) {
    return FeatureSet_MessageEncoding_Name(value);
  }
  static inline bool MessageEncoding_Parse(absl::string_view name, MessageEncoding* value) {
    return FeatureSet_MessageEncoding_Parse(name, value);
  }
  using JsonFormat = FeatureSet_JsonFormat;
  static constexpr JsonFormat JSON_FORMAT_UNKNOWN = FeatureSet_JsonFormat_JSON_FORMAT_UNKNOWN;
  static constexpr JsonFormat ALLOW = FeatureSet_JsonFormat_ALLOW;
  static constexpr JsonFormat LEGACY_BEST_EFFORT = FeatureSet_JsonFormat_LEGACY_BEST_EFFORT;
  static inline bool JsonFormat_IsValid(int value) {
    return FeatureSet_JsonFormat_IsValid(value);
  }
  static constexpr JsonFormat JsonFormat_MIN = FeatureSet_JsonFormat_JsonFormat_MIN;
  static constexpr JsonFormat JsonFormat_MAX = FeatureSet_JsonFormat_JsonFormat_MAX;
  static constexpr int JsonFormat_ARRAYSIZE = FeatureSet_JsonFormat_JsonFormat_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* JsonFormat_descriptor() {
    return FeatureSet_JsonFormat_descriptor();
  }
  template <typename T>
  static inline const std::string& JsonFormat_Name(T value) {
    return FeatureSet_JsonFormat_Name(value);
  }
  static inline bool JsonFormat_Parse(absl::string_view name, JsonFormat* value) {
    return FeatureSet_JsonFormat_Parse(name, value);
  }

  // accessors -------------------------------------------------------
  enum : int {
    kFieldPresenceFieldNumber = 1,
    kEnumTypeFieldNumber = 2,
    kRepeatedFieldEncodingFieldNumber = 3,
    kUtf8ValidationFieldNumber = 4,
    kMessageEncodingFieldNumber = 5,
    kJsonFormatFieldNumber = 6,
  };
  // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
  bool has_field_presence() const;
  void clear_field_presence() ;
  ::google::protobuf::FeatureSet_FieldPresence field_presence() const;
  void set_field_presence(::google::protobuf::FeatureSet_FieldPresence value);

  private:
  ::google::protobuf::FeatureSet_FieldPresence _internal_field_presence() const;
  void _internal_set_field_presence(::google::protobuf::FeatureSet_FieldPresence value);

  public:
  // optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
  bool has_enum_type() const;
  void clear_enum_type() ;
  ::google::protobuf::FeatureSet_EnumType enum_type() const;
  void set_enum_type(::google::protobuf::FeatureSet_EnumType value);

  private:
  ::google::protobuf::FeatureSet_EnumType _internal_enum_type() const;
  void _internal_set_enum_type(::google::protobuf::FeatureSet_EnumType value);

  public:
  // optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
  bool has_repeated_field_encoding() const;
  void clear_repeated_field_encoding() ;
  ::google::protobuf::FeatureSet_RepeatedFieldEncoding repeated_field_encoding() const;
  void set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value);

  private:
  ::google::protobuf::FeatureSet_RepeatedFieldEncoding _internal_repeated_field_encoding() const;
  void _internal_set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value);

  public:
  // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
  bool has_utf8_validation() const;
  void clear_utf8_validation() ;
  ::google::protobuf::FeatureSet_Utf8Validation utf8_validation() const;
  void set_utf8_validation(::google::protobuf::FeatureSet_Utf8Validation value);

  private:
  ::google::protobuf::FeatureSet_Utf8Validation _internal_utf8_validation() const;
  void _internal_set_utf8_validation(::google::protobuf::FeatureSet_Utf8Validation value);

  public:
  // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
  bool has_message_encoding() const;
  void clear_message_encoding() ;
  ::google::protobuf::FeatureSet_MessageEncoding message_encoding() const;
  void set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value);

  private:
  ::google::protobuf::FeatureSet_MessageEncoding _internal_message_encoding() const;
  void _internal_set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value);

  public:
  // optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
  bool has_json_format() const;
  void clear_json_format() ;
  ::google::protobuf::FeatureSet_JsonFormat json_format() const;
  void set_json_format(::google::protobuf::FeatureSet_JsonFormat value);

  private:
  ::google::protobuf::FeatureSet_JsonFormat _internal_json_format() const;
  void _internal_set_json_format(::google::protobuf::FeatureSet_JsonFormat value);

  public:
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FeatureSet, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSet)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 6, 6,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FeatureSet_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FeatureSet& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    int field_presence_;
    int enum_type_;
    int repeated_field_encoding_;
    int utf8_validation_;
    int message_encoding_;
    int json_format_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions.Declaration) */ {
 public:
  inline ExtensionRangeOptions_Declaration() : ExtensionRangeOptions_Declaration(nullptr) {}
  ~ExtensionRangeOptions_Declaration() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions_Declaration(
      ::google::protobuf::internal::ConstantInitialized);

  inline ExtensionRangeOptions_Declaration(const ExtensionRangeOptions_Declaration& from) : ExtensionRangeOptions_Declaration(nullptr, from) {}
  inline ExtensionRangeOptions_Declaration(ExtensionRangeOptions_Declaration&& from) noexcept
      : ExtensionRangeOptions_Declaration(nullptr, std::move(from)) {}
  inline ExtensionRangeOptions_Declaration& operator=(const ExtensionRangeOptions_Declaration& from) {
    CopyFrom(from);
    return *this;
  }
  inline ExtensionRangeOptions_Declaration& operator=(ExtensionRangeOptions_Declaration&& from) noexcept {
    if (this == &from) return *this;
    if (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ExtensionRangeOptions_Declaration& default_instance() {
    return *internal_default_instance();
  }
  static inline const ExtensionRangeOptions_Declaration* internal_default_instance() {
    return reinterpret_cast<const ExtensionRangeOptions_Declaration*>(
        &_ExtensionRangeOptions_Declaration_default_instance_);
  }
  static constexpr int kIndexInFileMessages = 5;
  friend void swap(ExtensionRangeOptions_Declaration& a, ExtensionRangeOptions_Declaration& b) { a.Swap(&b); }
  inline void Swap(ExtensionRangeOptions_Declaration* other) {
    if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ExtensionRangeOptions_Declaration* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  ExtensionRangeOptions_Declaration* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<ExtensionRangeOptions_Declaration>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const ExtensionRangeOptions_Declaration& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const ExtensionRangeOptions_Declaration& from) { ExtensionRangeOptions_Declaration::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(ExtensionRangeOptions_Declaration* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.ExtensionRangeOptions.Declaration"; }

 protected:
  explicit ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena);
  ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena, const ExtensionRangeOptions_Declaration& from);
  ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena, ExtensionRangeOptions_Declaration&& from) noexcept
      : ExtensionRangeOptions_Declaration(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kFullNameFieldNumber = 2,
    kTypeFieldNumber = 3,
    kNumberFieldNumber = 1,
    kReservedFieldNumber = 5,
    kRepeatedFieldNumber = 6,
  };
  // optional string full_name = 2;
  bool has_full_name() const;
  void clear_full_name() ;
  const std::string& full_name() const;
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_full_name(Arg_&& arg, Args_... args);
  std::string* mutable_full_name();
  PROTOBUF_NODISCARD std::string* release_full_name();
  void set_allocated_full_name(std::string* value);

  private:
  const std::string& _internal_full_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_full_name(
      const std::string& value);
  std::string* _internal_mutable_full_name();

  public:
  // optional string type = 3;
  bool has_type() const;
  void clear_type() ;
  const std::string& type() const;
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_type(Arg_&& arg, Args_... args);
  std::string* mutable_type();
  PROTOBUF_NODISCARD std::string* release_type();
  void set_allocated_type(std::string* value);

  private:
  const std::string& _internal_type() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_type(
      const std::string& value);
  std::string* _internal_mutable_type();

  public:
  // optional int32 number = 1;
  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 bool reserved = 5;
  bool has_reserved() const;
  void clear_reserved() ;
  bool reserved() const;
  void set_reserved(bool value);

  private:
  bool _internal_reserved() const;
  void _internal_set_reserved(bool value);

  public:
  // optional bool repeated = 6;
  bool has_repeated() const;
  void clear_repeated() ;
  bool repeated() const;
  void set_repeated(bool value);

  private:
  bool _internal_repeated() const;
  void _internal_set_repeated(bool value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions.Declaration)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 0,
      71, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_ExtensionRangeOptions_Declaration_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const ExtensionRangeOptions_Declaration& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr full_name_;
    ::google::protobuf::internal::ArenaStringPtr type_;
    ::int32_t number_;
    bool reserved_;
    bool repeated_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ {
 public:
  inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {}
  ~EnumDescriptorProto_EnumReservedRange() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange(
      ::google::protobuf::internal::ConstantInitialized);

  inline EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from) : EnumDescriptorProto_EnumReservedRange(nullptr, from) {}
  inline EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept
      : EnumDescriptorProto_EnumReservedRange(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 9;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  EnumDescriptorProto_EnumReservedRange* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<EnumDescriptorProto_EnumReservedRange>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const EnumDescriptorProto_EnumReservedRange& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) { EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(EnumDescriptorProto_EnumReservedRange* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.EnumDescriptorProto.EnumReservedRange"; }

 protected:
  explicit EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena);
  EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena, const EnumDescriptorProto_EnumReservedRange& from);
  EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena, EnumDescriptorProto_EnumReservedRange&& from) noexcept
      : EnumDescriptorProto_EnumReservedRange(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      1, 2, 0,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_EnumDescriptorProto_EnumReservedRange_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const EnumDescriptorProto_EnumReservedRange& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::int32_t start_;
    ::int32_t end_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ {
 public:
  inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {}
  ~DescriptorProto_ReservedRange() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange(
      ::google::protobuf::internal::ConstantInitialized);

  inline DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) : DescriptorProto_ReservedRange(nullptr, from) {}
  inline DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept
      : DescriptorProto_ReservedRange(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(DescriptorProto_ReservedRange* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  DescriptorProto_ReservedRange* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<DescriptorProto_ReservedRange>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const DescriptorProto_ReservedRange& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const DescriptorProto_ReservedRange& from) { DescriptorProto_ReservedRange::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(DescriptorProto_ReservedRange* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto.ReservedRange"; }

 protected:
  explicit DescriptorProto_ReservedRange(::google::protobuf::Arena* arena);
  DescriptorProto_ReservedRange(::google::protobuf::Arena* arena, const DescriptorProto_ReservedRange& from);
  DescriptorProto_ReservedRange(::google::protobuf::Arena* arena, DescriptorProto_ReservedRange&& from) noexcept
      : DescriptorProto_ReservedRange(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      1, 2, 0,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_DescriptorProto_ReservedRange_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const DescriptorProto_ReservedRange& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::int32_t start_;
    ::int32_t end_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT UninterpretedOption final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ {
 public:
  inline UninterpretedOption() : UninterpretedOption(nullptr) {}
  ~UninterpretedOption() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR UninterpretedOption(
      ::google::protobuf::internal::ConstantInitialized);

  inline UninterpretedOption(const UninterpretedOption& from) : UninterpretedOption(nullptr, from) {}
  inline UninterpretedOption(UninterpretedOption&& from) noexcept
      : UninterpretedOption(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 25;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(UninterpretedOption* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  UninterpretedOption* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<UninterpretedOption>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const UninterpretedOption& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const UninterpretedOption& from) { UninterpretedOption::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(UninterpretedOption* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.UninterpretedOption"; }

 protected:
  explicit UninterpretedOption(::google::protobuf::Arena* arena);
  UninterpretedOption(::google::protobuf::Arena* arena, const UninterpretedOption& from);
  UninterpretedOption(::google::protobuf::Arena* arena, UninterpretedOption&& from) noexcept
      : UninterpretedOption(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using NamePart = UninterpretedOption_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() ;
  ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>* mutable_name();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>& _internal_name() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>* _internal_mutable_name();
  public:
  const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
  ::google::protobuf::UninterpretedOption_NamePart* add_name();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>& name() const;
  // optional string identifier_value = 3;
  bool has_identifier_value() const;
  void clear_identifier_value() ;
  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* value);

  private:
  const std::string& _internal_identifier_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_identifier_value(
      const std::string& value);
  std::string* _internal_mutable_identifier_value();

  public:
  // optional bytes string_value = 7;
  bool has_string_value() const;
  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* value);

  private:
  const std::string& _internal_string_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_string_value(
      const std::string& value);
  std::string* _internal_mutable_string_value();

  public:
  // optional string aggregate_value = 8;
  bool has_aggregate_value() const;
  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* value);

  private:
  const std::string& _internal_aggregate_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_aggregate_value(
      const std::string& value);
  std::string* _internal_mutable_aggregate_value();

  public:
  // optional uint64 positive_int_value = 4;
  bool has_positive_int_value() const;
  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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 7, 1,
      75, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_UninterpretedOption_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const UninterpretedOption& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
    ::google::protobuf::internal::ArenaStringPtr identifier_value_;
    ::google::protobuf::internal::ArenaStringPtr string_value_;
    ::google::protobuf::internal::ArenaStringPtr aggregate_value_;
    ::uint64_t positive_int_value_;
    ::int64_t negative_int_value_;
    double double_value_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT SourceCodeInfo final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ {
 public:
  inline SourceCodeInfo() : SourceCodeInfo(nullptr) {}
  ~SourceCodeInfo() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR SourceCodeInfo(
      ::google::protobuf::internal::ConstantInitialized);

  inline SourceCodeInfo(const SourceCodeInfo& from) : SourceCodeInfo(nullptr, from) {}
  inline SourceCodeInfo(SourceCodeInfo&& from) noexcept
      : SourceCodeInfo(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 30;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(SourceCodeInfo* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  SourceCodeInfo* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<SourceCodeInfo>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const SourceCodeInfo& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const SourceCodeInfo& from) { SourceCodeInfo::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(SourceCodeInfo* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.SourceCodeInfo"; }

 protected:
  explicit SourceCodeInfo(::google::protobuf::Arena* arena);
  SourceCodeInfo(::google::protobuf::Arena* arena, const SourceCodeInfo& from);
  SourceCodeInfo(::google::protobuf::Arena* arena, SourceCodeInfo&& from) noexcept
      : SourceCodeInfo(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using Location = SourceCodeInfo_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() ;
  ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>* mutable_location();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>& _internal_location() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>* _internal_mutable_location();
  public:
  const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
  ::google::protobuf::SourceCodeInfo_Location* add_location();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>& location() const;
  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      0, 1, 1,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_SourceCodeInfo_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const SourceCodeInfo& from_msg);
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT GeneratedCodeInfo final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ {
 public:
  inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {}
  ~GeneratedCodeInfo() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo(
      ::google::protobuf::internal::ConstantInitialized);

  inline GeneratedCodeInfo(const GeneratedCodeInfo& from) : GeneratedCodeInfo(nullptr, from) {}
  inline GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept
      : GeneratedCodeInfo(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 32;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GeneratedCodeInfo* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  GeneratedCodeInfo* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<GeneratedCodeInfo>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const GeneratedCodeInfo& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const GeneratedCodeInfo& from) { GeneratedCodeInfo::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(GeneratedCodeInfo* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.GeneratedCodeInfo"; }

 protected:
  explicit GeneratedCodeInfo(::google::protobuf::Arena* arena);
  GeneratedCodeInfo(::google::protobuf::Arena* arena, const GeneratedCodeInfo& from);
  GeneratedCodeInfo(::google::protobuf::Arena* arena, GeneratedCodeInfo&& from) noexcept
      : GeneratedCodeInfo(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using Annotation = GeneratedCodeInfo_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() ;
  ::google::protobuf::GeneratedCodeInfo_Annotation* mutable_annotation(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>* mutable_annotation();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>& _internal_annotation() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>* _internal_mutable_annotation();
  public:
  const ::google::protobuf::GeneratedCodeInfo_Annotation& annotation(int index) const;
  ::google::protobuf::GeneratedCodeInfo_Annotation* add_annotation();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>& annotation() const;
  // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      0, 1, 1,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_GeneratedCodeInfo_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const GeneratedCodeInfo& from_msg);
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) */ {
 public:
  inline FeatureSetDefaults_FeatureSetEditionDefault() : FeatureSetDefaults_FeatureSetEditionDefault(nullptr) {}
  ~FeatureSetDefaults_FeatureSetEditionDefault() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FeatureSetDefaults_FeatureSetEditionDefault(
      ::google::protobuf::internal::ConstantInitialized);

  inline FeatureSetDefaults_FeatureSetEditionDefault(const FeatureSetDefaults_FeatureSetEditionDefault& from) : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, from) {}
  inline FeatureSetDefaults_FeatureSetEditionDefault(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept
      : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, std::move(from)) {}
  inline FeatureSetDefaults_FeatureSetEditionDefault& operator=(const FeatureSetDefaults_FeatureSetEditionDefault& from) {
    CopyFrom(from);
    return *this;
  }
  inline FeatureSetDefaults_FeatureSetEditionDefault& operator=(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept {
    if (this == &from) return *this;
    if (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FeatureSetDefaults_FeatureSetEditionDefault& default_instance() {
    return *internal_default_instance();
  }
  static inline const FeatureSetDefaults_FeatureSetEditionDefault* internal_default_instance() {
    return reinterpret_cast<const FeatureSetDefaults_FeatureSetEditionDefault*>(
        &_FeatureSetDefaults_FeatureSetEditionDefault_default_instance_);
  }
  static constexpr int kIndexInFileMessages = 27;
  friend void swap(FeatureSetDefaults_FeatureSetEditionDefault& a, FeatureSetDefaults_FeatureSetEditionDefault& b) { a.Swap(&b); }
  inline void Swap(FeatureSetDefaults_FeatureSetEditionDefault* other) {
    if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FeatureSetDefaults_FeatureSetEditionDefault* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FeatureSetDefaults_FeatureSetEditionDefault* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FeatureSetDefaults_FeatureSetEditionDefault>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from) { FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FeatureSetDefaults_FeatureSetEditionDefault* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault"; }

 protected:
  explicit FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena);
  FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena, const FeatureSetDefaults_FeatureSetEditionDefault& from);
  FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena, FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept
      : FeatureSetDefaults_FeatureSetEditionDefault(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kOverridableFeaturesFieldNumber = 4,
    kFixedFeaturesFieldNumber = 5,
    kEditionFieldNumber = 3,
  };
  // optional .google.protobuf.FeatureSet overridable_features = 4;
  bool has_overridable_features() const;
  void clear_overridable_features() ;
  const ::google::protobuf::FeatureSet& overridable_features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_overridable_features();
  ::google::protobuf::FeatureSet* mutable_overridable_features();
  void set_allocated_overridable_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_overridable_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_overridable_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_overridable_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_overridable_features();

  public:
  // optional .google.protobuf.FeatureSet fixed_features = 5;
  bool has_fixed_features() const;
  void clear_fixed_features() ;
  const ::google::protobuf::FeatureSet& fixed_features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_fixed_features();
  ::google::protobuf::FeatureSet* mutable_fixed_features();
  void set_allocated_fixed_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_fixed_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_fixed_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_fixed_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_fixed_features();

  public:
  // optional .google.protobuf.Edition edition = 3;
  bool has_edition() const;
  void clear_edition() ;
  ::google::protobuf::Edition edition() const;
  void set_edition(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_edition() const;
  void _internal_set_edition(::google::protobuf::Edition value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 3, 3,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FeatureSetDefaults_FeatureSetEditionDefault_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FeatureSetDefaults_FeatureSetEditionDefault& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::FeatureSet* overridable_features_;
    ::google::protobuf::FeatureSet* fixed_features_;
    int edition_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ServiceOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ {
 public:
  inline ServiceOptions() : ServiceOptions(nullptr) {}
  ~ServiceOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR ServiceOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline ServiceOptions(const ServiceOptions& from) : ServiceOptions(nullptr, from) {}
  inline ServiceOptions(ServiceOptions&& from) noexcept
      : ServiceOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 22;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ServiceOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  ServiceOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<ServiceOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const ServiceOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const ServiceOptions& from) { ServiceOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(ServiceOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.ServiceOptions"; }

 protected:
  explicit ServiceOptions(::google::protobuf::Arena* arena);
  ServiceOptions(::google::protobuf::Arena* arena, const ServiceOptions& from);
  ServiceOptions(::google::protobuf::Arena* arena, ServiceOptions&& from) noexcept
      : ServiceOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 34,
    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() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 34;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // 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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ServiceOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 3, 2,
      0, 12>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_ServiceOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const ServiceOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    bool deprecated_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT OneofOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ {
 public:
  inline OneofOptions() : OneofOptions(nullptr) {}
  ~OneofOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR OneofOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline OneofOptions(const OneofOptions& from) : OneofOptions(nullptr, from) {}
  inline OneofOptions(OneofOptions&& from) noexcept
      : OneofOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 19;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(OneofOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  OneofOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<OneofOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const OneofOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const OneofOptions& from) { OneofOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(OneofOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.OneofOptions"; }

 protected:
  explicit OneofOptions(::google::protobuf::Arena* arena);
  OneofOptions(::google::protobuf::Arena* arena, const OneofOptions& from);
  OneofOptions(::google::protobuf::Arena* arena, OneofOptions&& from) noexcept
      : OneofOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 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() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 1;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<OneofOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 2, 2,
      0, 7>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_OneofOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const OneofOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT MethodOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ {
 public:
  inline MethodOptions() : MethodOptions(nullptr) {}
  ~MethodOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR MethodOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline MethodOptions(const MethodOptions& from) : MethodOptions(nullptr, from) {}
  inline MethodOptions(MethodOptions&& from) noexcept
      : MethodOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 23;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MethodOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  MethodOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<MethodOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const MethodOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const MethodOptions& from) { MethodOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(MethodOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.MethodOptions"; }

 protected:
  explicit MethodOptions(::google::protobuf::Arena* arena);
  MethodOptions(::google::protobuf::Arena* arena, const MethodOptions& from);
  MethodOptions(::google::protobuf::Arena* arena, MethodOptions&& from) noexcept
      : MethodOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 ::google::protobuf::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,
    kFeaturesFieldNumber = 35,
    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() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 35;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // 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() ;
  ::google::protobuf::MethodOptions_IdempotencyLevel idempotency_level() const;
  void set_idempotency_level(::google::protobuf::MethodOptions_IdempotencyLevel value);

  private:
  ::google::protobuf::MethodOptions_IdempotencyLevel _internal_idempotency_level() const;
  void _internal_set_idempotency_level(::google::protobuf::MethodOptions_IdempotencyLevel value);

  public:
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MethodOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 4, 3,
      0, 12>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_MethodOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const MethodOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    bool deprecated_;
    int idempotency_level_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT MessageOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ {
 public:
  inline MessageOptions() : MessageOptions(nullptr) {}
  ~MessageOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR MessageOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline MessageOptions(const MessageOptions& from) : MessageOptions(nullptr, from) {}
  inline MessageOptions(MessageOptions&& from) noexcept
      : MessageOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 15;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MessageOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  MessageOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<MessageOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const MessageOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const MessageOptions& from) { MessageOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(MessageOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.MessageOptions"; }

 protected:
  explicit MessageOptions(::google::protobuf::Arena* arena);
  MessageOptions(::google::protobuf::Arena* arena, const MessageOptions& from);
  MessageOptions(::google::protobuf::Arena* arena, MessageOptions&& from) noexcept
      : MessageOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 12,
    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() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 12;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // 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];
  [[deprecated]]  bool has_deprecated_legacy_json_field_conflicts() const;
  [[deprecated]]  void clear_deprecated_legacy_json_field_conflicts() ;
  [[deprecated]] bool deprecated_legacy_json_field_conflicts() const;
  [[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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<MessageOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 7, 2,
      0, 7>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_MessageOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const MessageOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    bool message_set_wire_format_;
    bool no_standard_descriptor_accessor_;
    bool deprecated_;
    bool map_entry_;
    bool deprecated_legacy_json_field_conflicts_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FileOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ {
 public:
  inline FileOptions() : FileOptions(nullptr) {}
  ~FileOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FileOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline FileOptions(const FileOptions& from) : FileOptions(nullptr, from) {}
  inline FileOptions(FileOptions&& from) noexcept
      : FileOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 14;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FileOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FileOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FileOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FileOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FileOptions& from) { FileOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FileOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FileOptions"; }

 protected:
  explicit FileOptions(::google::protobuf::Arena* arena);
  FileOptions(::google::protobuf::Arena* arena, const FileOptions& from);
  FileOptions(::google::protobuf::Arena* arena, FileOptions&& from) noexcept
      : FileOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 ::google::protobuf::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,
    kFeaturesFieldNumber = 50,
    kJavaMultipleFilesFieldNumber = 10,
    kJavaGenerateEqualsAndHashFieldNumber = 20,
    kJavaStringCheckUtf8FieldNumber = 27,
    kCcGenericServicesFieldNumber = 16,
    kJavaGenericServicesFieldNumber = 17,
    kPyGenericServicesFieldNumber = 18,
    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() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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* value);

  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* value);

  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* value);

  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* value);

  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* value);

  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* value);

  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* value);

  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* value);

  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* value);

  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* value);

  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 .google.protobuf.FeatureSet features = 50;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  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];
  [[deprecated]]  bool has_java_generate_equals_and_hash() const;
  [[deprecated]]  void clear_java_generate_equals_and_hash() ;
  [[deprecated]] bool java_generate_equals_and_hash() const;
  [[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 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() ;
  ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
  void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);

  private:
  ::google::protobuf::FileOptions_OptimizeMode _internal_optimize_for() const;
  void _internal_set_optimize_for(::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FileOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      5, 21, 3,
      202, 12>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FileOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FileOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::internal::ArenaStringPtr java_package_;
    ::google::protobuf::internal::ArenaStringPtr java_outer_classname_;
    ::google::protobuf::internal::ArenaStringPtr go_package_;
    ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
    ::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
    ::google::protobuf::internal::ArenaStringPtr swift_prefix_;
    ::google::protobuf::internal::ArenaStringPtr php_class_prefix_;
    ::google::protobuf::internal::ArenaStringPtr php_namespace_;
    ::google::protobuf::internal::ArenaStringPtr php_metadata_namespace_;
    ::google::protobuf::internal::ArenaStringPtr ruby_package_;
    ::google::protobuf::FeatureSet* features_;
    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 deprecated_;
    int optimize_for_;
    bool cc_enable_arenas_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FieldOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ {
 public:
  inline FieldOptions() : FieldOptions(nullptr) {}
  ~FieldOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FieldOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline FieldOptions(const FieldOptions& from) : FieldOptions(nullptr, from) {}
  inline FieldOptions(FieldOptions&& from) noexcept
      : FieldOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 18;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FieldOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FieldOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FieldOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FieldOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FieldOptions& from) { FieldOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FieldOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions"; }

 protected:
  explicit FieldOptions(::google::protobuf::Arena* arena);
  FieldOptions(::google::protobuf::Arena* arena, const FieldOptions& from);
  FieldOptions(::google::protobuf::Arena* arena, FieldOptions&& from) noexcept
      : FieldOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using EditionDefault = FieldOptions_EditionDefault;
  using FeatureSupport = FieldOptions_FeatureSupport;
  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 ::google::protobuf::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 ::google::protobuf::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 ::google::protobuf::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 ::google::protobuf::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 {
    kTargetsFieldNumber = 19,
    kEditionDefaultsFieldNumber = 20,
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 21,
    kFeatureSupportFieldNumber = 22,
    kCtypeFieldNumber = 1,
    kJstypeFieldNumber = 6,
    kPackedFieldNumber = 2,
    kLazyFieldNumber = 5,
    kUnverifiedLazyFieldNumber = 15,
    kDeprecatedFieldNumber = 3,
    kWeakFieldNumber = 10,
    kDebugRedactFieldNumber = 16,
    kRetentionFieldNumber = 17,
  };
  // repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19;
  int targets_size() const;
  private:
  int _internal_targets_size() const;

  public:
  void clear_targets() ;
  public:
  ::google::protobuf::FieldOptions_OptionTargetType targets(int index) const;
  void set_targets(int index, ::google::protobuf::FieldOptions_OptionTargetType value);
  void add_targets(::google::protobuf::FieldOptions_OptionTargetType value);
  const ::google::protobuf::RepeatedField<int>& targets() const;
  ::google::protobuf::RepeatedField<int>* mutable_targets();

  private:
  const ::google::protobuf::RepeatedField<int>& _internal_targets() const;
  ::google::protobuf::RepeatedField<int>* _internal_mutable_targets();

  public:
  // repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20;
  int edition_defaults_size() const;
  private:
  int _internal_edition_defaults_size() const;

  public:
  void clear_edition_defaults() ;
  ::google::protobuf::FieldOptions_EditionDefault* mutable_edition_defaults(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>* mutable_edition_defaults();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>& _internal_edition_defaults() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>* _internal_mutable_edition_defaults();
  public:
  const ::google::protobuf::FieldOptions_EditionDefault& edition_defaults(int index) const;
  ::google::protobuf::FieldOptions_EditionDefault* add_edition_defaults();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>& edition_defaults() const;
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;

  public:
  void clear_uninterpreted_option() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 21;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22;
  bool has_feature_support() const;
  void clear_feature_support() ;
  const ::google::protobuf::FieldOptions_FeatureSupport& feature_support() const;
  PROTOBUF_NODISCARD ::google::protobuf::FieldOptions_FeatureSupport* release_feature_support();
  ::google::protobuf::FieldOptions_FeatureSupport* mutable_feature_support();
  void set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value);
  void unsafe_arena_set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value);
  ::google::protobuf::FieldOptions_FeatureSupport* unsafe_arena_release_feature_support();

  private:
  const ::google::protobuf::FieldOptions_FeatureSupport& _internal_feature_support() const;
  ::google::protobuf::FieldOptions_FeatureSupport* _internal_mutable_feature_support();

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

  private:
  ::google::protobuf::FieldOptions_CType _internal_ctype() const;
  void _internal_set_ctype(::google::protobuf::FieldOptions_CType value);

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

  private:
  ::google::protobuf::FieldOptions_JSType _internal_jstype() const;
  void _internal_set_jstype(::google::protobuf::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() ;
  ::google::protobuf::FieldOptions_OptionRetention retention() const;
  void set_retention(::google::protobuf::FieldOptions_OptionRetention value);

  private:
  ::google::protobuf::FieldOptions_OptionRetention _internal_retention() const;
  void _internal_set_retention(::google::protobuf::FieldOptions_OptionRetention value);

  public:
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<FieldOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      4, 14, 8,
      0, 7>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FieldOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FieldOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedField<int> targets_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldOptions_EditionDefault > edition_defaults_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    ::google::protobuf::FieldOptions_FeatureSupport* feature_support_;
    int ctype_;
    int jstype_;
    bool packed_;
    bool lazy_;
    bool unverified_lazy_;
    bool deprecated_;
    bool weak_;
    bool debug_redact_;
    int retention_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FeatureSetDefaults final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSetDefaults) */ {
 public:
  inline FeatureSetDefaults() : FeatureSetDefaults(nullptr) {}
  ~FeatureSetDefaults() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FeatureSetDefaults(
      ::google::protobuf::internal::ConstantInitialized);

  inline FeatureSetDefaults(const FeatureSetDefaults& from) : FeatureSetDefaults(nullptr, from) {}
  inline FeatureSetDefaults(FeatureSetDefaults&& from) noexcept
      : FeatureSetDefaults(nullptr, std::move(from)) {}
  inline FeatureSetDefaults& operator=(const FeatureSetDefaults& from) {
    CopyFrom(from);
    return *this;
  }
  inline FeatureSetDefaults& operator=(FeatureSetDefaults&& from) noexcept {
    if (this == &from) return *this;
    if (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const FeatureSetDefaults& default_instance() {
    return *internal_default_instance();
  }
  static inline const FeatureSetDefaults* internal_default_instance() {
    return reinterpret_cast<const FeatureSetDefaults*>(
        &_FeatureSetDefaults_default_instance_);
  }
  static constexpr int kIndexInFileMessages = 28;
  friend void swap(FeatureSetDefaults& a, FeatureSetDefaults& b) { a.Swap(&b); }
  inline void Swap(FeatureSetDefaults* other) {
    if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FeatureSetDefaults* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FeatureSetDefaults* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FeatureSetDefaults>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FeatureSetDefaults& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FeatureSetDefaults& from) { FeatureSetDefaults::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FeatureSetDefaults* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSetDefaults"; }

 protected:
  explicit FeatureSetDefaults(::google::protobuf::Arena* arena);
  FeatureSetDefaults(::google::protobuf::Arena* arena, const FeatureSetDefaults& from);
  FeatureSetDefaults(::google::protobuf::Arena* arena, FeatureSetDefaults&& from) noexcept
      : FeatureSetDefaults(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using FeatureSetEditionDefault = FeatureSetDefaults_FeatureSetEditionDefault;

  // accessors -------------------------------------------------------
  enum : int {
    kDefaultsFieldNumber = 1,
    kMinimumEditionFieldNumber = 4,
    kMaximumEditionFieldNumber = 5,
  };
  // repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1;
  int defaults_size() const;
  private:
  int _internal_defaults_size() const;

  public:
  void clear_defaults() ;
  ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* mutable_defaults(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>* mutable_defaults();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>& _internal_defaults() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>* _internal_mutable_defaults();
  public:
  const ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault& defaults(int index) const;
  ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* add_defaults();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>& defaults() const;
  // optional .google.protobuf.Edition minimum_edition = 4;
  bool has_minimum_edition() const;
  void clear_minimum_edition() ;
  ::google::protobuf::Edition minimum_edition() const;
  void set_minimum_edition(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_minimum_edition() const;
  void _internal_set_minimum_edition(::google::protobuf::Edition value);

  public:
  // optional .google.protobuf.Edition maximum_edition = 5;
  bool has_maximum_edition() const;
  void clear_maximum_edition() ;
  ::google::protobuf::Edition maximum_edition() const;
  void set_maximum_edition(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_maximum_edition() const;
  void _internal_set_maximum_edition(::google::protobuf::Edition value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSetDefaults)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      1, 3, 3,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FeatureSetDefaults_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FeatureSetDefaults& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault > defaults_;
    int minimum_edition_;
    int maximum_edition_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ExtensionRangeOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ {
 public:
  inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {}
  ~ExtensionRangeOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline ExtensionRangeOptions(const ExtensionRangeOptions& from) : ExtensionRangeOptions(nullptr, from) {}
  inline ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept
      : ExtensionRangeOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 6;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ExtensionRangeOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  ExtensionRangeOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<ExtensionRangeOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const ExtensionRangeOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const ExtensionRangeOptions& from) { ExtensionRangeOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(ExtensionRangeOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.ExtensionRangeOptions"; }

 protected:
  explicit ExtensionRangeOptions(::google::protobuf::Arena* arena);
  ExtensionRangeOptions(::google::protobuf::Arena* arena, const ExtensionRangeOptions& from);
  ExtensionRangeOptions(::google::protobuf::Arena* arena, ExtensionRangeOptions&& from) noexcept
      : ExtensionRangeOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using Declaration = ExtensionRangeOptions_Declaration;
  using VerificationState = ExtensionRangeOptions_VerificationState;
  static constexpr VerificationState DECLARATION = ExtensionRangeOptions_VerificationState_DECLARATION;
  static constexpr VerificationState UNVERIFIED = ExtensionRangeOptions_VerificationState_UNVERIFIED;
  static inline bool VerificationState_IsValid(int value) {
    return ExtensionRangeOptions_VerificationState_IsValid(value);
  }
  static constexpr VerificationState VerificationState_MIN = ExtensionRangeOptions_VerificationState_VerificationState_MIN;
  static constexpr VerificationState VerificationState_MAX = ExtensionRangeOptions_VerificationState_VerificationState_MAX;
  static constexpr int VerificationState_ARRAYSIZE = ExtensionRangeOptions_VerificationState_VerificationState_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor* VerificationState_descriptor() {
    return ExtensionRangeOptions_VerificationState_descriptor();
  }
  template <typename T>
  static inline const std::string& VerificationState_Name(T value) {
    return ExtensionRangeOptions_VerificationState_Name(value);
  }
  static inline bool VerificationState_Parse(absl::string_view name, VerificationState* value) {
    return ExtensionRangeOptions_VerificationState_Parse(name, value);
  }

  // accessors -------------------------------------------------------
  enum : int {
    kDeclarationFieldNumber = 2,
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 50,
    kVerificationFieldNumber = 3,
  };
  // repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE];
  int declaration_size() const;
  private:
  int _internal_declaration_size() const;

  public:
  void clear_declaration() ;
  ::google::protobuf::ExtensionRangeOptions_Declaration* mutable_declaration(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>* mutable_declaration();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>& _internal_declaration() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>* _internal_mutable_declaration();
  public:
  const ::google::protobuf::ExtensionRangeOptions_Declaration& declaration(int index) const;
  ::google::protobuf::ExtensionRangeOptions_Declaration* add_declaration();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>& declaration() const;
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;

  public:
  void clear_uninterpreted_option() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 50;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE];
  bool has_verification() const;
  void clear_verification() ;
  ::google::protobuf::ExtensionRangeOptions_VerificationState verification() const;
  void set_verification(::google::protobuf::ExtensionRangeOptions_VerificationState value);

  private:
  ::google::protobuf::ExtensionRangeOptions_VerificationState _internal_verification() const;
  void _internal_set_verification(::google::protobuf::ExtensionRangeOptions_VerificationState value);

  public:
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<ExtensionRangeOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 4, 4,
      0, 12>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_ExtensionRangeOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const ExtensionRangeOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::ExtensionRangeOptions_Declaration > declaration_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    int verification_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumValueOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ {
 public:
  inline EnumValueOptions() : EnumValueOptions(nullptr) {}
  ~EnumValueOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR EnumValueOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline EnumValueOptions(const EnumValueOptions& from) : EnumValueOptions(nullptr, from) {}
  inline EnumValueOptions(EnumValueOptions&& from) noexcept
      : EnumValueOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 21;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumValueOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  EnumValueOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<EnumValueOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const EnumValueOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const EnumValueOptions& from) { EnumValueOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(EnumValueOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.EnumValueOptions"; }

 protected:
  explicit EnumValueOptions(::google::protobuf::Arena* arena);
  EnumValueOptions(::google::protobuf::Arena* arena, const EnumValueOptions& from);
  EnumValueOptions(::google::protobuf::Arena* arena, EnumValueOptions&& from) noexcept
      : EnumValueOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 2,
    kFeatureSupportFieldNumber = 4,
    kDeprecatedFieldNumber = 1,
    kDebugRedactFieldNumber = 3,
  };
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int uninterpreted_option_size() const;
  private:
  int _internal_uninterpreted_option_size() const;

  public:
  void clear_uninterpreted_option() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 2;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4;
  bool has_feature_support() const;
  void clear_feature_support() ;
  const ::google::protobuf::FieldOptions_FeatureSupport& feature_support() const;
  PROTOBUF_NODISCARD ::google::protobuf::FieldOptions_FeatureSupport* release_feature_support();
  ::google::protobuf::FieldOptions_FeatureSupport* mutable_feature_support();
  void set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value);
  void unsafe_arena_set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value);
  ::google::protobuf::FieldOptions_FeatureSupport* unsafe_arena_release_feature_support();

  private:
  const ::google::protobuf::FieldOptions_FeatureSupport& _internal_feature_support() const;
  ::google::protobuf::FieldOptions_FeatureSupport* _internal_mutable_feature_support();

  public:
  // 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:
  // optional bool debug_redact = 3 [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:
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumValueOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 3,
      0, 7>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_EnumValueOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const EnumValueOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    ::google::protobuf::FieldOptions_FeatureSupport* feature_support_;
    bool deprecated_;
    bool debug_redact_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumOptions final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ {
 public:
  inline EnumOptions() : EnumOptions(nullptr) {}
  ~EnumOptions() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR EnumOptions(
      ::google::protobuf::internal::ConstantInitialized);

  inline EnumOptions(const EnumOptions& from) : EnumOptions(nullptr, from) {}
  inline EnumOptions(EnumOptions&& from) noexcept
      : EnumOptions(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 20;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumOptions* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  EnumOptions* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<EnumOptions>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const EnumOptions& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const EnumOptions& from) { EnumOptions::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(EnumOptions* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.EnumOptions"; }

 protected:
  explicit EnumOptions(::google::protobuf::Arena* arena);
  EnumOptions(::google::protobuf::Arena* arena, const EnumOptions& from);
  EnumOptions(::google::protobuf::Arena* arena, EnumOptions&& from) noexcept
      : EnumOptions(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kUninterpretedOptionFieldNumber = 999,
    kFeaturesFieldNumber = 7,
    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() ;
  ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option();
  public:
  const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
  ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const;
  // optional .google.protobuf.FeatureSet features = 7;
  bool has_features() const;
  void clear_features() ;
  const ::google::protobuf::FeatureSet& features() const;
  PROTOBUF_NODISCARD ::google::protobuf::FeatureSet* release_features();
  ::google::protobuf::FeatureSet* mutable_features();
  void set_allocated_features(::google::protobuf::FeatureSet* value);
  void unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value);
  ::google::protobuf::FeatureSet* unsafe_arena_release_features();

  private:
  const ::google::protobuf::FeatureSet& _internal_features() const;
  ::google::protobuf::FeatureSet* _internal_mutable_features();

  public:
  // 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];
  [[deprecated]]  bool has_deprecated_legacy_json_field_conflicts() const;
  [[deprecated]]  void clear_deprecated_legacy_json_field_conflicts() ;
  [[deprecated]] bool deprecated_legacy_json_field_conflicts() const;
  [[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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Singular>
  inline bool HasExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.Has(id.number());
  }

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

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            typename = typename _proto_TypeTraits::Repeated>
  inline int ExtensionSize(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const {
    return _impl_._extensions_.ExtensionSize(id.number());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, id.default_value());
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), _field_type, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void UnsafeArenaSetAllocatedExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  PROTOBUF_NODISCARD inline
      typename _proto_TypeTraits::Singular::MutableType
      ReleaseExtension(
          const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                           _field_type, _is_packed>& id) {
    return _proto_TypeTraits::Release(id.number(), _field_type, &_impl_._extensions_);
  }
  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Singular::MutableType
  UnsafeArenaReleaseExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) {
    return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,
                                                 &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<!_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed,
            std::enable_if_t<_proto_TypeTraits::kLifetimeBound, int> = 0>
  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Get(id.number(), _impl_._extensions_, index);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id,
      int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::Mutable(id.number(), index, &_impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void SetExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    typename _proto_TypeTraits::Repeated::MutableType to_add =
        _proto_TypeTraits::Add(id.number(), _field_type, &_impl_._extensions_);
    return to_add;
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline void AddExtension(
      const ::google::protobuf::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, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&
  GetRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::GetRepeated(id.number(), _impl_._extensions_);
  }

  template <typename _proto_TypeTraits, ::google::protobuf::internal::FieldType _field_type,
            bool _is_packed>
  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*
  MutableRepeatedExtension(
      const ::google::protobuf::internal::ExtensionIdentifier<EnumOptions, _proto_TypeTraits,
                                       _field_type, _is_packed>& id)
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,
                                              _is_packed, &_impl_._extensions_);
  }
  // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 2,
      0, 7>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_EnumOptions_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const EnumOptions& from_msg);
    ::google::protobuf::internal::ExtensionSet _extensions_;
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
    ::google::protobuf::FeatureSet* features_;
    bool allow_alias_;
    bool deprecated_;
    bool deprecated_legacy_json_field_conflicts_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT OneofDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ {
 public:
  inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {}
  ~OneofDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR OneofDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline OneofDescriptorProto(const OneofDescriptorProto& from) : OneofDescriptorProto(nullptr, from) {}
  inline OneofDescriptorProto(OneofDescriptorProto&& from) noexcept
      : OneofDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 8;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(OneofDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  OneofDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<OneofDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const OneofDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const OneofDescriptorProto& from) { OneofDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(OneofDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.OneofDescriptorProto"; }

 protected:
  explicit OneofDescriptorProto(::google::protobuf::Arena* arena);
  OneofDescriptorProto(::google::protobuf::Arena* arena, const OneofDescriptorProto& from);
  OneofDescriptorProto(::google::protobuf::Arena* arena, OneofDescriptorProto&& from) noexcept
      : OneofDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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* value);

  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 ::google::protobuf::OneofOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::OneofOptions* release_options();
  ::google::protobuf::OneofOptions* mutable_options();
  void set_allocated_options(::google::protobuf::OneofOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::OneofOptions* value);
  ::google::protobuf::OneofOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::OneofOptions& _internal_options() const;
  ::google::protobuf::OneofOptions* _internal_mutable_options();

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      1, 2, 1,
      49, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_OneofDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const OneofDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::OneofOptions* options_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT MethodDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ {
 public:
  inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {}
  ~MethodDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR MethodDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline MethodDescriptorProto(const MethodDescriptorProto& from) : MethodDescriptorProto(nullptr, from) {}
  inline MethodDescriptorProto(MethodDescriptorProto&& from) noexcept
      : MethodDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 13;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MethodDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  MethodDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<MethodDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const MethodDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const MethodDescriptorProto& from) { MethodDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(MethodDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.MethodDescriptorProto"; }

 protected:
  explicit MethodDescriptorProto(::google::protobuf::Arena* arena);
  MethodDescriptorProto(::google::protobuf::Arena* arena, const MethodDescriptorProto& from);
  MethodDescriptorProto(::google::protobuf::Arena* arena, MethodDescriptorProto&& from) noexcept
      : MethodDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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* value);

  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* value);

  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* value);

  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 ::google::protobuf::MethodOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::MethodOptions* release_options();
  ::google::protobuf::MethodOptions* mutable_options();
  void set_allocated_options(::google::protobuf::MethodOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::MethodOptions* value);
  ::google::protobuf::MethodOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::MethodOptions& _internal_options() const;
  ::google::protobuf::MethodOptions* _internal_mutable_options();

  public:
  // 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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 6, 1,
      71, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_MethodDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const MethodDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr input_type_;
    ::google::protobuf::internal::ArenaStringPtr output_type_;
    ::google::protobuf::MethodOptions* options_;
    bool client_streaming_;
    bool server_streaming_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FieldDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ {
 public:
  inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {}
  ~FieldDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FieldDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline FieldDescriptorProto(const FieldDescriptorProto& from) : FieldDescriptorProto(nullptr, from) {}
  inline FieldDescriptorProto(FieldDescriptorProto&& from) noexcept
      : FieldDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 7;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FieldDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FieldDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FieldDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FieldDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FieldDescriptorProto& from) { FieldDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FieldDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FieldDescriptorProto"; }

 protected:
  explicit FieldDescriptorProto(::google::protobuf::Arena* arena);
  FieldDescriptorProto(::google::protobuf::Arena* arena, const FieldDescriptorProto& from);
  FieldDescriptorProto(::google::protobuf::Arena* arena, FieldDescriptorProto&& from) noexcept
      : FieldDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 ::google::protobuf::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_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
  static constexpr Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
  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 ::google::protobuf::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* value);

  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* value);

  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* value);

  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* value);

  private:
  const std::string& _internal_default_value() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_default_value(
      const std::string& value);
  std::string* _internal_mutable_default_value();

  public:
  // optional string json_name = 10;
  bool has_json_name() const;
  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* value);

  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 ::google::protobuf::FieldOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::FieldOptions* release_options();
  ::google::protobuf::FieldOptions* mutable_options();
  void set_allocated_options(::google::protobuf::FieldOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::FieldOptions* value);
  ::google::protobuf::FieldOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::FieldOptions& _internal_options() const;
  ::google::protobuf::FieldOptions* _internal_mutable_options();

  public:
  // 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() ;
  ::google::protobuf::FieldDescriptorProto_Label label() const;
  void set_label(::google::protobuf::FieldDescriptorProto_Label value);

  private:
  ::google::protobuf::FieldDescriptorProto_Label _internal_label() const;
  void _internal_set_label(::google::protobuf::FieldDescriptorProto_Label value);

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

  private:
  ::google::protobuf::FieldDescriptorProto_Type _internal_type() const;
  void _internal_set_type(::google::protobuf::FieldDescriptorProto_Type value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      4, 11, 3,
      96, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FieldDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FieldDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr extendee_;
    ::google::protobuf::internal::ArenaStringPtr type_name_;
    ::google::protobuf::internal::ArenaStringPtr default_value_;
    ::google::protobuf::internal::ArenaStringPtr json_name_;
    ::google::protobuf::FieldOptions* options_;
    ::int32_t number_;
    ::int32_t oneof_index_;
    bool proto3_optional_;
    int label_;
    int type_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumValueDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ {
 public:
  inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {}
  ~EnumValueDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR EnumValueDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline EnumValueDescriptorProto(const EnumValueDescriptorProto& from) : EnumValueDescriptorProto(nullptr, from) {}
  inline EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept
      : EnumValueDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 11;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumValueDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  EnumValueDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<EnumValueDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const EnumValueDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const EnumValueDescriptorProto& from) { EnumValueDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(EnumValueDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.EnumValueDescriptorProto"; }

 protected:
  explicit EnumValueDescriptorProto(::google::protobuf::Arena* arena);
  EnumValueDescriptorProto(::google::protobuf::Arena* arena, const EnumValueDescriptorProto& from);
  EnumValueDescriptorProto(::google::protobuf::Arena* arena, EnumValueDescriptorProto&& from) noexcept
      : EnumValueDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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* value);

  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 ::google::protobuf::EnumValueOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::EnumValueOptions* release_options();
  ::google::protobuf::EnumValueOptions* mutable_options();
  void set_allocated_options(::google::protobuf::EnumValueOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::EnumValueOptions* value);
  ::google::protobuf::EnumValueOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::EnumValueOptions& _internal_options() const;
  ::google::protobuf::EnumValueOptions* _internal_mutable_options();

  public:
  // 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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 3, 1,
      53, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_EnumValueDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const EnumValueDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::EnumValueOptions* options_;
    ::int32_t number_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ {
 public:
  inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {}
  ~DescriptorProto_ExtensionRange() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange(
      ::google::protobuf::internal::ConstantInitialized);

  inline DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) : DescriptorProto_ExtensionRange(nullptr, from) {}
  inline DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept
      : DescriptorProto_ExtensionRange(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(DescriptorProto_ExtensionRange* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  DescriptorProto_ExtensionRange* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<DescriptorProto_ExtensionRange>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const DescriptorProto_ExtensionRange& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const DescriptorProto_ExtensionRange& from) { DescriptorProto_ExtensionRange::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(DescriptorProto_ExtensionRange* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto.ExtensionRange"; }

 protected:
  explicit DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena);
  DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena, const DescriptorProto_ExtensionRange& from);
  DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena, DescriptorProto_ExtensionRange&& from) noexcept
      : DescriptorProto_ExtensionRange(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 ::google::protobuf::ExtensionRangeOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::ExtensionRangeOptions* release_options();
  ::google::protobuf::ExtensionRangeOptions* mutable_options();
  void set_allocated_options(::google::protobuf::ExtensionRangeOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::ExtensionRangeOptions* value);
  ::google::protobuf::ExtensionRangeOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::ExtensionRangeOptions& _internal_options() const;
  ::google::protobuf::ExtensionRangeOptions* _internal_mutable_options();

  public:
  // 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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 3, 1,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_DescriptorProto_ExtensionRange_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const DescriptorProto_ExtensionRange& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::ExtensionRangeOptions* options_;
    ::int32_t start_;
    ::int32_t end_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT ServiceDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ {
 public:
  inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {}
  ~ServiceDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR ServiceDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline ServiceDescriptorProto(const ServiceDescriptorProto& from) : ServiceDescriptorProto(nullptr, from) {}
  inline ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept
      : ServiceDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 12;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ServiceDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  ServiceDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<ServiceDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const ServiceDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const ServiceDescriptorProto& from) { ServiceDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(ServiceDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.ServiceDescriptorProto"; }

 protected:
  explicit ServiceDescriptorProto(::google::protobuf::Arena* arena);
  ServiceDescriptorProto(::google::protobuf::Arena* arena, const ServiceDescriptorProto& from);
  ServiceDescriptorProto(::google::protobuf::Arena* arena, ServiceDescriptorProto&& from) noexcept
      : ServiceDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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() ;
  ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>* mutable_method();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>& _internal_method() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>* _internal_mutable_method();
  public:
  const ::google::protobuf::MethodDescriptorProto& method(int index) const;
  ::google::protobuf::MethodDescriptorProto* add_method();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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* value);

  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 ::google::protobuf::ServiceOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::ServiceOptions* release_options();
  ::google::protobuf::ServiceOptions* mutable_options();
  void set_allocated_options(::google::protobuf::ServiceOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::ServiceOptions* value);
  ::google::protobuf::ServiceOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::ServiceOptions& _internal_options() const;
  ::google::protobuf::ServiceOptions* _internal_mutable_options();

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 3, 2,
      51, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_ServiceDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const ServiceDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::ServiceOptions* options_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT EnumDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ {
 public:
  inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {}
  ~EnumDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR EnumDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline EnumDescriptorProto(const EnumDescriptorProto& from) : EnumDescriptorProto(nullptr, from) {}
  inline EnumDescriptorProto(EnumDescriptorProto&& from) noexcept
      : EnumDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 = 10;
  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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(EnumDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  EnumDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<EnumDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const EnumDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const EnumDescriptorProto& from) { EnumDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(EnumDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.EnumDescriptorProto"; }

 protected:
  explicit EnumDescriptorProto(::google::protobuf::Arena* arena);
  EnumDescriptorProto(::google::protobuf::Arena* arena, const EnumDescriptorProto& from);
  EnumDescriptorProto(::google::protobuf::Arena* arena, EnumDescriptorProto&& from) noexcept
      : EnumDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using EnumReservedRange = EnumDescriptorProto_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() ;
  ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>* mutable_value();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>& _internal_value() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>* _internal_mutable_value();
  public:
  const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
  ::google::protobuf::EnumValueDescriptorProto* add_value();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::EnumDescriptorProto_EnumReservedRange* mutable_reserved_range(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>* mutable_reserved_range();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>& _internal_reserved_range() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>* _internal_mutable_reserved_range();
  public:
  const ::google::protobuf::EnumDescriptorProto_EnumReservedRange& reserved_range(int index) const;
  ::google::protobuf::EnumDescriptorProto_EnumReservedRange* add_reserved_range();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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);
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_reserved_name(int index, Arg_&& value, Args_... args);
  std::string* add_reserved_name();
  template <typename Arg_ = const std::string&, typename... Args_>
  void add_reserved_name(Arg_&& value, Args_... args);
  const ::google::protobuf::RepeatedPtrField<std::string>& reserved_name() const;
  ::google::protobuf::RepeatedPtrField<std::string>* mutable_reserved_name();

  private:
  const ::google::protobuf::RepeatedPtrField<std::string>& _internal_reserved_name() const;
  ::google::protobuf::RepeatedPtrField<std::string>* _internal_mutable_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* value);

  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 ::google::protobuf::EnumOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::EnumOptions* release_options();
  ::google::protobuf::EnumOptions* mutable_options();
  void set_allocated_options(::google::protobuf::EnumOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::EnumOptions* value);
  ::google::protobuf::EnumOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::EnumOptions& _internal_options() const;
  ::google::protobuf::EnumOptions* _internal_mutable_options();

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 3,
      61, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_EnumDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const EnumDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto_EnumReservedRange > reserved_range_;
    ::google::protobuf::RepeatedPtrField<std::string> reserved_name_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::EnumOptions* options_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT DescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ {
 public:
  inline DescriptorProto() : DescriptorProto(nullptr) {}
  ~DescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR DescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline DescriptorProto(const DescriptorProto& from) : DescriptorProto(nullptr, from) {}
  inline DescriptorProto(DescriptorProto&& from) noexcept
      : DescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(DescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  DescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<DescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const DescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const DescriptorProto& from) { DescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(DescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto"; }

 protected:
  explicit DescriptorProto(::google::protobuf::Arena* arena);
  DescriptorProto(::google::protobuf::Arena* arena, const DescriptorProto& from);
  DescriptorProto(::google::protobuf::Arena* arena, DescriptorProto&& from) noexcept
      : DescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using ExtensionRange = DescriptorProto_ExtensionRange;
  using ReservedRange = DescriptorProto_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() ;
  ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* mutable_field();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& _internal_field() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* _internal_mutable_field();
  public:
  const ::google::protobuf::FieldDescriptorProto& field(int index) const;
  ::google::protobuf::FieldDescriptorProto* add_field();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* mutable_nested_type();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& _internal_nested_type() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* _internal_mutable_nested_type();
  public:
  const ::google::protobuf::DescriptorProto& nested_type(int index) const;
  ::google::protobuf::DescriptorProto* add_nested_type();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* mutable_enum_type();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& _internal_enum_type() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* _internal_mutable_enum_type();
  public:
  const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
  ::google::protobuf::EnumDescriptorProto* add_enum_type();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& enum_type() const;
  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  int extension_range_size() const;
  private:
  int _internal_extension_range_size() const;

  public:
  void clear_extension_range() ;
  ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>* mutable_extension_range();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>& _internal_extension_range() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>* _internal_mutable_extension_range();
  public:
  const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
  ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* mutable_extension();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& _internal_extension() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* _internal_mutable_extension();
  public:
  const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
  ::google::protobuf::FieldDescriptorProto* add_extension();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>* mutable_oneof_decl();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>& _internal_oneof_decl() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>* _internal_mutable_oneof_decl();
  public:
  const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
  ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::DescriptorProto_ReservedRange* mutable_reserved_range(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>* mutable_reserved_range();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>& _internal_reserved_range() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>* _internal_mutable_reserved_range();
  public:
  const ::google::protobuf::DescriptorProto_ReservedRange& reserved_range(int index) const;
  ::google::protobuf::DescriptorProto_ReservedRange* add_reserved_range();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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);
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_reserved_name(int index, Arg_&& value, Args_... args);
  std::string* add_reserved_name();
  template <typename Arg_ = const std::string&, typename... Args_>
  void add_reserved_name(Arg_&& value, Args_... args);
  const ::google::protobuf::RepeatedPtrField<std::string>& reserved_name() const;
  ::google::protobuf::RepeatedPtrField<std::string>* mutable_reserved_name();

  private:
  const ::google::protobuf::RepeatedPtrField<std::string>& _internal_reserved_name() const;
  ::google::protobuf::RepeatedPtrField<std::string>* _internal_mutable_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* value);

  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 ::google::protobuf::MessageOptions& options() const;
  PROTOBUF_NODISCARD ::google::protobuf::MessageOptions* release_options();
  ::google::protobuf::MessageOptions* mutable_options();
  void set_allocated_options(::google::protobuf::MessageOptions* value);
  void unsafe_arena_set_allocated_options(::google::protobuf::MessageOptions* value);
  ::google::protobuf::MessageOptions* unsafe_arena_release_options();

  private:
  const ::google::protobuf::MessageOptions& _internal_options() const;
  ::google::protobuf::MessageOptions* _internal_mutable_options();

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      4, 10, 8,
      65, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_DescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const DescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_;
    ::google::protobuf::RepeatedPtrField<std::string> reserved_name_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::MessageOptions* options_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FileDescriptorProto final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ {
 public:
  inline FileDescriptorProto() : FileDescriptorProto(nullptr) {}
  ~FileDescriptorProto() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FileDescriptorProto(
      ::google::protobuf::internal::ConstantInitialized);

  inline FileDescriptorProto(const FileDescriptorProto& from) : FileDescriptorProto(nullptr, from) {}
  inline FileDescriptorProto(FileDescriptorProto&& from) noexcept
      : FileDescriptorProto(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FileDescriptorProto* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FileDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FileDescriptorProto>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FileDescriptorProto& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FileDescriptorProto& from) { FileDescriptorProto::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FileDescriptorProto* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FileDescriptorProto"; }

 protected:
  explicit FileDescriptorProto(::google::protobuf::Arena* arena);
  FileDescriptorProto(::google::protobuf::Arena* arena, const FileDescriptorProto& from);
  FileDescriptorProto(::google::protobuf::Arena* arena, FileDescriptorProto&& from) noexcept
      : FileDescriptorProto(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kDependencyFieldNumber = 3,
    kMessageTypeFieldNumber = 4,
    kEnumTypeFieldNumber = 5,
    kServiceFieldNumber = 6,
    kExtensionFieldNumber = 7,
    kPublicDependencyFieldNumber = 10,
    kWeakDependencyFieldNumber = 11,
    kNameFieldNumber = 1,
    kPackageFieldNumber = 2,
    kSyntaxFieldNumber = 12,
    kOptionsFieldNumber = 8,
    kSourceCodeInfoFieldNumber = 9,
    kEditionFieldNumber = 14,
  };
  // 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);
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_dependency(int index, Arg_&& value, Args_... args);
  std::string* add_dependency();
  template <typename Arg_ = const std::string&, typename... Args_>
  void add_dependency(Arg_&& value, Args_... args);
  const ::google::protobuf::RepeatedPtrField<std::string>& dependency() const;
  ::google::protobuf::RepeatedPtrField<std::string>* mutable_dependency();

  private:
  const ::google::protobuf::RepeatedPtrField<std::string>& _internal_dependency() const;
  ::google::protobuf::RepeatedPtrField<std::string>* _internal_mutable_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() ;
  ::google::protobuf::DescriptorProto* mutable_message_type(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* mutable_message_type();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& _internal_message_type() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* _internal_mutable_message_type();
  public:
  const ::google::protobuf::DescriptorProto& message_type(int index) const;
  ::google::protobuf::DescriptorProto* add_message_type();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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() ;
  ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* mutable_enum_type();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& _internal_enum_type() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* _internal_mutable_enum_type();
  public:
  const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
  ::google::protobuf::EnumDescriptorProto* add_enum_type();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& enum_type() const;
  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  int service_size() const;
  private:
  int _internal_service_size() const;

  public:
  void clear_service() ;
  ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>* mutable_service();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>& _internal_service() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>* _internal_mutable_service();
  public:
  const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
  ::google::protobuf::ServiceDescriptorProto* add_service();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>& service() const;
  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  int extension_size() const;
  private:
  int _internal_extension_size() const;

  public:
  void clear_extension() ;
  ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* mutable_extension();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& _internal_extension() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* _internal_mutable_extension();
  public:
  const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
  ::google::protobuf::FieldDescriptorProto* add_extension();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::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 ::google::protobuf::RepeatedField<::int32_t>& public_dependency() const;
  ::google::protobuf::RepeatedField<::int32_t>* mutable_public_dependency();

  private:
  const ::google::protobuf::RepeatedField<::int32_t>& _internal_public_dependency() const;
  ::google::protobuf::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 ::google::protobuf::RepeatedField<::int32_t>& weak_dependency() const;
  ::google::protobuf::RepeatedField<::int32_t>* mutable_weak_dependency();

  private:
  const ::google::protobuf::RepeatedField<::int32_t>& _internal_weak_dependency() const;
  ::google::protobuf::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* value);

  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* value);

  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* value);

  private:
  const std::string& _internal_syntax() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_syntax(
      const std::string& value);
  std::string* _internal_mutable_syntax();

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

  private:
  const ::google::protobuf::FileOptions& _internal_options() const;
  ::google::protobuf::FileOptions* _internal_mutable_options();

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

  private:
  const ::google::protobuf::SourceCodeInfo& _internal_source_code_info() const;
  ::google::protobuf::SourceCodeInfo* _internal_mutable_source_code_info();

  public:
  // optional .google.protobuf.Edition edition = 14;
  bool has_edition() const;
  void clear_edition() ;
  ::google::protobuf::Edition edition() const;
  void set_edition(::google::protobuf::Edition value);

  private:
  ::google::protobuf::Edition _internal_edition() const;
  void _internal_set_edition(::google::protobuf::Edition value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      4, 13, 7,
      79, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FileDescriptorProto_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FileDescriptorProto& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField<std::string> dependency_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
    ::google::protobuf::RepeatedField<::int32_t> public_dependency_;
    ::google::protobuf::RepeatedField<::int32_t> weak_dependency_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr package_;
    ::google::protobuf::internal::ArenaStringPtr syntax_;
    ::google::protobuf::FileOptions* options_;
    ::google::protobuf::SourceCodeInfo* source_code_info_;
    int edition_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
};
// -------------------------------------------------------------------

class PROTOBUF_EXPORT FileDescriptorSet final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ {
 public:
  inline FileDescriptorSet() : FileDescriptorSet(nullptr) {}
  ~FileDescriptorSet() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR FileDescriptorSet(
      ::google::protobuf::internal::ConstantInitialized);

  inline FileDescriptorSet(const FileDescriptorSet& from) : FileDescriptorSet(nullptr, from) {}
  inline FileDescriptorSet(FileDescriptorSet&& from) noexcept
      : FileDescriptorSet(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(FileDescriptorSet* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  FileDescriptorSet* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<FileDescriptorSet>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const FileDescriptorSet& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const FileDescriptorSet& from) { FileDescriptorSet::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(FileDescriptorSet* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.FileDescriptorSet"; }

 protected:
  explicit FileDescriptorSet(::google::protobuf::Arena* arena);
  FileDescriptorSet(::google::protobuf::Arena* arena, const FileDescriptorSet& from);
  FileDescriptorSet(::google::protobuf::Arena* arena, FileDescriptorSet&& from) noexcept
      : FileDescriptorSet(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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() ;
  ::google::protobuf::FileDescriptorProto* mutable_file(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* mutable_file();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& _internal_file() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* _internal_mutable_file();
  public:
  const ::google::protobuf::FileDescriptorProto& file(int index) const;
  ::google::protobuf::FileDescriptorProto* add_file();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& file() const;
  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      0, 1, 1,
      0, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_FileDescriptorSet_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const FileDescriptorSet& from_msg);
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  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 _internal_file().size();
}
inline int FileDescriptorSet::file_size() const {
  return _internal_file_size();
}
inline void FileDescriptorSet::clear_file() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.file_.Clear();
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
  return _internal_mutable_file()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* FileDescriptorSet::mutable_file()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_file();
}
inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
  return _internal_file().Get(index);
}
inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::FileDescriptorProto* _add = _internal_mutable_file()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& FileDescriptorSet::file() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
  return _internal_file();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>&
FileDescriptorSet::_internal_file() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.file_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>*
FileDescriptorSet::_internal_mutable_file() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FileDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
}
inline std::string* FileDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void FileDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* FileDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* FileDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& FileDescriptorProto::package() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.package_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
}
inline std::string* FileDescriptorProto::mutable_package() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.package_.Get();
}
inline void FileDescriptorProto::_internal_set_package(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.package_.Set(value, GetArena());
}
inline std::string* FileDescriptorProto::_internal_mutable_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.package_.Mutable( GetArena());
}
inline std::string* FileDescriptorProto::release_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_package(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.package_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.package_.IsDefault()) {
          _impl_.package_.Set("", GetArena());
        }
  #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 _internal_dependency().size();
}
inline int FileDescriptorProto::dependency_size() const {
  return _internal_dependency_size();
}
inline void FileDescriptorProto::clear_dependency() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.dependency_.Clear();
}
inline std::string* FileDescriptorProto::add_dependency() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  std::string* _s = _internal_mutable_dependency()->Add();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency)
  return _s;
}
inline const std::string& FileDescriptorProto::dependency(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
  return _internal_dependency().Get(index);
}
inline std::string* FileDescriptorProto::mutable_dependency(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
  return _internal_mutable_dependency()->Mutable(index);
}
template <typename Arg_, typename... Args_>
inline void FileDescriptorProto::set_dependency(int index, Arg_&& value, Args_... args) {
  ::google::protobuf::internal::AssignToString(
      *_internal_mutable_dependency()->Mutable(index),
      std::forward<Arg_>(value), args... );
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
}
template <typename Arg_, typename... Args_>
inline void FileDescriptorProto::add_dependency(Arg_&& value, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::internal::AddToRepeatedPtrField(*_internal_mutable_dependency(),
                               std::forward<Arg_>(value),
                               args... );
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
FileDescriptorProto::dependency() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
  return _internal_dependency();
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
FileDescriptorProto::mutable_dependency() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_dependency();
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
FileDescriptorProto::_internal_dependency() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.dependency_;
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
FileDescriptorProto::_internal_mutable_dependency() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.dependency_;
}

// repeated int32 public_dependency = 10;
inline int FileDescriptorProto::_internal_public_dependency_size() const {
  return _internal_public_dependency().size();
}
inline int FileDescriptorProto::public_dependency_size() const {
  return _internal_public_dependency_size();
}
inline void FileDescriptorProto::clear_public_dependency() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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().Get(index);
}
inline void FileDescriptorProto::set_public_dependency(int index, ::int32_t value) {
  _internal_mutable_public_dependency()->Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
}
inline void FileDescriptorProto::add_public_dependency(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _internal_mutable_public_dependency()->Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
}
inline const ::google::protobuf::RepeatedField<::int32_t>& FileDescriptorProto::public_dependency() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
  return _internal_public_dependency();
}
inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::mutable_public_dependency()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_public_dependency();
}
inline const ::google::protobuf::RepeatedField<::int32_t>&
FileDescriptorProto::_internal_public_dependency() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.public_dependency_;
}
inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::_internal_mutable_public_dependency() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.public_dependency_;
}

// repeated int32 weak_dependency = 11;
inline int FileDescriptorProto::_internal_weak_dependency_size() const {
  return _internal_weak_dependency().size();
}
inline int FileDescriptorProto::weak_dependency_size() const {
  return _internal_weak_dependency_size();
}
inline void FileDescriptorProto::clear_weak_dependency() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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().Get(index);
}
inline void FileDescriptorProto::set_weak_dependency(int index, ::int32_t value) {
  _internal_mutable_weak_dependency()->Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
}
inline void FileDescriptorProto::add_weak_dependency(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _internal_mutable_weak_dependency()->Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
}
inline const ::google::protobuf::RepeatedField<::int32_t>& FileDescriptorProto::weak_dependency() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
  return _internal_weak_dependency();
}
inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::mutable_weak_dependency()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_weak_dependency();
}
inline const ::google::protobuf::RepeatedField<::int32_t>&
FileDescriptorProto::_internal_weak_dependency() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.weak_dependency_;
}
inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::_internal_mutable_weak_dependency() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.weak_dependency_;
}

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

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

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

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

// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::has_options() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.options_ != nullptr);
  return value;
}
inline void FileDescriptorProto::clear_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FileOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FileOptions&>(::google::protobuf::_FileOptions_default_instance_);
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
  return _internal_options();
}
inline void FileDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::FileOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::FileOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000008u;
  ::google::protobuf::FileOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000008u;
  ::google::protobuf::FileOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FileOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::FileOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000008u;
  ::google::protobuf::FileOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
  return _msg;
}
inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::FileOptions*>(value);
  // @@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] & 0x00000010u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.source_code_info_ != nullptr);
  return value;
}
inline void FileDescriptorProto::clear_source_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.source_code_info_ != nullptr) _impl_.source_code_info_->Clear();
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::SourceCodeInfo* p = _impl_.source_code_info_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::SourceCodeInfo&>(::google::protobuf::_SourceCodeInfo_default_instance_);
}
inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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(::google::protobuf::SourceCodeInfo* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.source_code_info_);
  }
  _impl_.source_code_info_ = reinterpret_cast<::google::protobuf::SourceCodeInfo*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000010u;
  ::google::protobuf::SourceCodeInfo* released = _impl_.source_code_info_;
  _impl_.source_code_info_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::unsafe_arena_release_source_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info)

  _impl_._has_bits_[0] &= ~0x00000010u;
  ::google::protobuf::SourceCodeInfo* temp = _impl_.source_code_info_;
  _impl_.source_code_info_ = nullptr;
  return temp;
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.source_code_info_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::SourceCodeInfo>(GetArena());
    _impl_.source_code_info_ = reinterpret_cast<::google::protobuf::SourceCodeInfo*>(p);
  }
  return _impl_.source_code_info_;
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000010u;
  ::google::protobuf::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(::google::protobuf::SourceCodeInfo* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.source_code_info_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }

  _impl_.source_code_info_ = reinterpret_cast<::google::protobuf::SourceCodeInfo*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.syntax_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& FileDescriptorProto::syntax() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.syntax_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
}
inline std::string* FileDescriptorProto::mutable_syntax() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.syntax_.Get();
}
inline void FileDescriptorProto::_internal_set_syntax(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.syntax_.Set(value, GetArena());
}
inline std::string* FileDescriptorProto::_internal_mutable_syntax() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.syntax_.Mutable( GetArena());
}
inline std::string* FileDescriptorProto::release_syntax() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileDescriptorProto::set_allocated_syntax(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.syntax_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.syntax_.IsDefault()) {
          _impl_.syntax_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax)
}

// optional .google.protobuf.Edition edition = 14;
inline bool FileDescriptorProto::has_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline void FileDescriptorProto::clear_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000020u;
}
inline ::google::protobuf::Edition FileDescriptorProto::edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.edition)
  return _internal_edition();
}
inline void FileDescriptorProto::set_edition(::google::protobuf::Edition value) {
  _internal_set_edition(value);
  _impl_._has_bits_[0] |= 0x00000020u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.edition)
}
inline ::google::protobuf::Edition FileDescriptorProto::_internal_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.edition_);
}
inline void FileDescriptorProto::_internal_set_edition(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.edition_ = value;
}

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

// 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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
}
inline ::int32_t DescriptorProto_ExtensionRange::_internal_start() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.start_;
}
inline void DescriptorProto_ExtensionRange::_internal_set_start(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
}
inline ::int32_t DescriptorProto_ExtensionRange::_internal_end() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.end_;
}
inline void DescriptorProto_ExtensionRange::_internal_set_end(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::ExtensionRangeOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::ExtensionRangeOptions&>(::google::protobuf::_ExtensionRangeOptions_default_instance_);
}
inline const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options)
  return _internal_options();
}
inline void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options(::google::protobuf::ExtensionRangeOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::ExtensionRangeOptions*>(value);
  if (value != nullptr) {
    _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 ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::ExtensionRangeOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::ExtensionRangeOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::ExtensionRangeOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::ExtensionRangeOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::ExtensionRangeOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options)
  return _msg;
}
inline void DescriptorProto_ExtensionRange::set_allocated_options(::google::protobuf::ExtensionRangeOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::ExtensionRangeOptions*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000001u;
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start)
}
inline ::int32_t DescriptorProto_ReservedRange::_internal_start() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.start_;
}
inline void DescriptorProto_ReservedRange::_internal_set_start(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end)
}
inline ::int32_t DescriptorProto_ReservedRange::_internal_end() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.end_;
}
inline void DescriptorProto_ReservedRange::_internal_set_end(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& DescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
}
inline std::string* DescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void DescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* DescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* DescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void DescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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 _internal_field().size();
}
inline int DescriptorProto::field_size() const {
  return _internal_field_size();
}
inline void DescriptorProto::clear_field() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.field_.Clear();
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
  return _internal_mutable_field()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* DescriptorProto::mutable_field()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_field();
}
inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
  return _internal_field().Get(index);
}
inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::FieldDescriptorProto* _add = _internal_mutable_field()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& DescriptorProto::field() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
  return _internal_field();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>&
DescriptorProto::_internal_field() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.field_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>*
DescriptorProto::_internal_mutable_field() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.field_;
}

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

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

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

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

// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
inline int DescriptorProto::_internal_oneof_decl_size() const {
  return _internal_oneof_decl().size();
}
inline int DescriptorProto::oneof_decl_size() const {
  return _internal_oneof_decl_size();
}
inline void DescriptorProto::clear_oneof_decl() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.oneof_decl_.Clear();
}
inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
  return _internal_mutable_oneof_decl()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>* DescriptorProto::mutable_oneof_decl()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_oneof_decl();
}
inline const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
  return _internal_oneof_decl().Get(index);
}
inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::OneofDescriptorProto* _add = _internal_mutable_oneof_decl()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>& DescriptorProto::oneof_decl() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
  return _internal_oneof_decl();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>&
DescriptorProto::_internal_oneof_decl() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.oneof_decl_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>*
DescriptorProto::_internal_mutable_oneof_decl() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::MessageOptions& DescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::MessageOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::MessageOptions&>(::google::protobuf::_MessageOptions_default_instance_);
}
inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
  return _internal_options();
}
inline void DescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::MessageOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::MessageOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options)
}
inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::MessageOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::MessageOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::MessageOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::MessageOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::MessageOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
  return _msg;
}
inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::MessageOptions*>(value);
  // @@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 _internal_reserved_range().size();
}
inline int DescriptorProto::reserved_range_size() const {
  return _internal_reserved_range_size();
}
inline void DescriptorProto::clear_reserved_range() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.reserved_range_.Clear();
}
inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range)
  return _internal_mutable_reserved_range()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>* DescriptorProto::mutable_reserved_range()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_reserved_range();
}
inline const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range)
  return _internal_reserved_range().Get(index);
}
inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::DescriptorProto_ReservedRange* _add = _internal_mutable_reserved_range()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>& DescriptorProto::reserved_range() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
  return _internal_reserved_range();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>&
DescriptorProto::_internal_reserved_range() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.reserved_range_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>*
DescriptorProto::_internal_mutable_reserved_range() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.reserved_range_;
}

// repeated string reserved_name = 10;
inline int DescriptorProto::_internal_reserved_name_size() const {
  return _internal_reserved_name().size();
}
inline int DescriptorProto::reserved_name_size() const {
  return _internal_reserved_name_size();
}
inline void DescriptorProto::clear_reserved_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.reserved_name_.Clear();
}
inline std::string* DescriptorProto::add_reserved_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  std::string* _s = _internal_mutable_reserved_name()->Add();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name)
  return _s;
}
inline const std::string& DescriptorProto::reserved_name(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name)
  return _internal_reserved_name().Get(index);
}
inline std::string* DescriptorProto::mutable_reserved_name(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name)
  return _internal_mutable_reserved_name()->Mutable(index);
}
template <typename Arg_, typename... Args_>
inline void DescriptorProto::set_reserved_name(int index, Arg_&& value, Args_... args) {
  ::google::protobuf::internal::AssignToString(
      *_internal_mutable_reserved_name()->Mutable(index),
      std::forward<Arg_>(value), args... );
  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
}
template <typename Arg_, typename... Args_>
inline void DescriptorProto::add_reserved_name(Arg_&& value, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::internal::AddToRepeatedPtrField(*_internal_mutable_reserved_name(),
                               std::forward<Arg_>(value),
                               args... );
  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
DescriptorProto::reserved_name() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name)
  return _internal_reserved_name();
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
DescriptorProto::mutable_reserved_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_reserved_name();
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
DescriptorProto::_internal_reserved_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.reserved_name_;
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
DescriptorProto::_internal_mutable_reserved_name() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.reserved_name_;
}

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

// ExtensionRangeOptions_Declaration

// optional int32 number = 1;
inline bool ExtensionRangeOptions_Declaration::has_number() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void ExtensionRangeOptions_Declaration::clear_number() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.number_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::int32_t ExtensionRangeOptions_Declaration::number() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.Declaration.number)
  return _internal_number();
}
inline void ExtensionRangeOptions_Declaration::set_number(::int32_t value) {
  _internal_set_number(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.number)
}
inline ::int32_t ExtensionRangeOptions_Declaration::_internal_number() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.number_;
}
inline void ExtensionRangeOptions_Declaration::_internal_set_number(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.number_ = value;
}

// optional string full_name = 2;
inline bool ExtensionRangeOptions_Declaration::has_full_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void ExtensionRangeOptions_Declaration::clear_full_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.full_name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ExtensionRangeOptions_Declaration::full_name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.Declaration.full_name)
  return _internal_full_name();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void ExtensionRangeOptions_Declaration::set_full_name(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.full_name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.full_name)
}
inline std::string* ExtensionRangeOptions_Declaration::mutable_full_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  std::string* _s = _internal_mutable_full_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.Declaration.full_name)
  return _s;
}
inline const std::string& ExtensionRangeOptions_Declaration::_internal_full_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.full_name_.Get();
}
inline void ExtensionRangeOptions_Declaration::_internal_set_full_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.full_name_.Set(value, GetArena());
}
inline std::string* ExtensionRangeOptions_Declaration::_internal_mutable_full_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.full_name_.Mutable( GetArena());
}
inline std::string* ExtensionRangeOptions_Declaration::release_full_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.ExtensionRangeOptions.Declaration.full_name)
  if ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.full_name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.full_name_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void ExtensionRangeOptions_Declaration::set_allocated_full_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.full_name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.full_name_.IsDefault()) {
          _impl_.full_name_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ExtensionRangeOptions.Declaration.full_name)
}

// optional string type = 3;
inline bool ExtensionRangeOptions_Declaration::has_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void ExtensionRangeOptions_Declaration::clear_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.type_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& ExtensionRangeOptions_Declaration::type() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.Declaration.type)
  return _internal_type();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void ExtensionRangeOptions_Declaration::set_type(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.type_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.type)
}
inline std::string* ExtensionRangeOptions_Declaration::mutable_type() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  std::string* _s = _internal_mutable_type();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.Declaration.type)
  return _s;
}
inline const std::string& ExtensionRangeOptions_Declaration::_internal_type() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.type_.Get();
}
inline void ExtensionRangeOptions_Declaration::_internal_set_type(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.type_.Set(value, GetArena());
}
inline std::string* ExtensionRangeOptions_Declaration::_internal_mutable_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.type_.Mutable( GetArena());
}
inline std::string* ExtensionRangeOptions_Declaration::release_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.ExtensionRangeOptions.Declaration.type)
  if ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* released = _impl_.type_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.type_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void ExtensionRangeOptions_Declaration::set_allocated_type(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.type_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.type_.IsDefault()) {
          _impl_.type_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ExtensionRangeOptions.Declaration.type)
}

// optional bool reserved = 5;
inline bool ExtensionRangeOptions_Declaration::has_reserved() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline void ExtensionRangeOptions_Declaration::clear_reserved() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.reserved_ = false;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline bool ExtensionRangeOptions_Declaration::reserved() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.Declaration.reserved)
  return _internal_reserved();
}
inline void ExtensionRangeOptions_Declaration::set_reserved(bool value) {
  _internal_set_reserved(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.reserved)
}
inline bool ExtensionRangeOptions_Declaration::_internal_reserved() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.reserved_;
}
inline void ExtensionRangeOptions_Declaration::_internal_set_reserved(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.reserved_ = value;
}

// optional bool repeated = 6;
inline bool ExtensionRangeOptions_Declaration::has_repeated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void ExtensionRangeOptions_Declaration::clear_repeated() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.repeated_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline bool ExtensionRangeOptions_Declaration::repeated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.Declaration.repeated)
  return _internal_repeated();
}
inline void ExtensionRangeOptions_Declaration::set_repeated(bool value) {
  _internal_set_repeated(value);
  _impl_._has_bits_[0] |= 0x00000010u;
  // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.repeated)
}
inline bool ExtensionRangeOptions_Declaration::_internal_repeated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.repeated_;
}
inline void ExtensionRangeOptions_Declaration::_internal_set_repeated(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.repeated_ = value;
}

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

// ExtensionRangeOptions

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int ExtensionRangeOptions::_internal_uninterpreted_option_size() const {
  return _internal_uninterpreted_option().size();
}
inline int ExtensionRangeOptions::uninterpreted_option_size() const {
  return _internal_uninterpreted_option_size();
}
inline void ExtensionRangeOptions::clear_uninterpreted_option() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.uninterpreted_option_.Clear();
}
inline ::google::protobuf::UninterpretedOption* ExtensionRangeOptions::mutable_uninterpreted_option(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
  return _internal_mutable_uninterpreted_option()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* ExtensionRangeOptions::mutable_uninterpreted_option()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_uninterpreted_option();
}
inline const ::google::protobuf::UninterpretedOption& ExtensionRangeOptions::uninterpreted_option(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
  return _internal_uninterpreted_option().Get(index);
}
inline ::google::protobuf::UninterpretedOption* ExtensionRangeOptions::add_uninterpreted_option() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::UninterpretedOption* _add = _internal_mutable_uninterpreted_option()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& ExtensionRangeOptions::uninterpreted_option() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option)
  return _internal_uninterpreted_option();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>&
ExtensionRangeOptions::_internal_uninterpreted_option() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>*
ExtensionRangeOptions::_internal_mutable_uninterpreted_option() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.uninterpreted_option_;
}

// repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE];
inline int ExtensionRangeOptions::_internal_declaration_size() const {
  return _internal_declaration().size();
}
inline int ExtensionRangeOptions::declaration_size() const {
  return _internal_declaration_size();
}
inline void ExtensionRangeOptions::clear_declaration() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.declaration_.Clear();
}
inline ::google::protobuf::ExtensionRangeOptions_Declaration* ExtensionRangeOptions::mutable_declaration(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.declaration)
  return _internal_mutable_declaration()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>* ExtensionRangeOptions::mutable_declaration()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ExtensionRangeOptions.declaration)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_declaration();
}
inline const ::google::protobuf::ExtensionRangeOptions_Declaration& ExtensionRangeOptions::declaration(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.declaration)
  return _internal_declaration().Get(index);
}
inline ::google::protobuf::ExtensionRangeOptions_Declaration* ExtensionRangeOptions::add_declaration() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::ExtensionRangeOptions_Declaration* _add = _internal_mutable_declaration()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.ExtensionRangeOptions.declaration)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>& ExtensionRangeOptions::declaration() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.ExtensionRangeOptions.declaration)
  return _internal_declaration();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>&
ExtensionRangeOptions::_internal_declaration() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.declaration_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>*
ExtensionRangeOptions::_internal_mutable_declaration() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.declaration_;
}

// optional .google.protobuf.FeatureSet features = 50;
inline bool ExtensionRangeOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void ExtensionRangeOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& ExtensionRangeOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& ExtensionRangeOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.features)
  return _internal_features();
}
inline void ExtensionRangeOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ExtensionRangeOptions.features)
}
inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.ExtensionRangeOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.features)
  return _msg;
}
inline void ExtensionRangeOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ExtensionRangeOptions.features)
}

// optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE];
inline bool ExtensionRangeOptions::has_verification() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void ExtensionRangeOptions::clear_verification() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.verification_ = 1;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::google::protobuf::ExtensionRangeOptions_VerificationState ExtensionRangeOptions::verification() const {
  // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.verification)
  return _internal_verification();
}
inline void ExtensionRangeOptions::set_verification(::google::protobuf::ExtensionRangeOptions_VerificationState value) {
  _internal_set_verification(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.verification)
}
inline ::google::protobuf::ExtensionRangeOptions_VerificationState ExtensionRangeOptions::_internal_verification() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::ExtensionRangeOptions_VerificationState>(_impl_.verification_);
}
inline void ExtensionRangeOptions::_internal_set_verification(::google::protobuf::ExtensionRangeOptions_VerificationState value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::ExtensionRangeOptions_VerificationState_IsValid(value));
  _impl_.verification_ = value;
}

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

// 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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FieldDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
}
inline std::string* FieldDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void FieldDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* FieldDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* FieldDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000040u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
}
inline ::int32_t FieldDescriptorProto::_internal_number() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.number_;
}
inline void FieldDescriptorProto::_internal_set_number(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.label_ = 1;
  _impl_._has_bits_[0] &= ~0x00000200u;
}
inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
  return _internal_label();
}
inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
  _internal_set_label(value);
  _impl_._has_bits_[0] |= 0x00000200u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
}
inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FieldDescriptorProto_Label>(_impl_.label_);
}
inline void FieldDescriptorProto::_internal_set_label(::google::protobuf::FieldDescriptorProto_Label value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.type_ = 1;
  _impl_._has_bits_[0] &= ~0x00000400u;
}
inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
  return _internal_type();
}
inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
  _internal_set_type(value);
  _impl_._has_bits_[0] |= 0x00000400u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
}
inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FieldDescriptorProto_Type>(_impl_.type_);
}
inline void FieldDescriptorProto::_internal_set_type(::google::protobuf::FieldDescriptorProto_Type value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.type_name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& FieldDescriptorProto::type_name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.type_name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
}
inline std::string* FieldDescriptorProto::mutable_type_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.type_name_.Get();
}
inline void FieldDescriptorProto::_internal_set_type_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.type_name_.Set(value, GetArena());
}
inline std::string* FieldDescriptorProto::_internal_mutable_type_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.type_name_.Mutable( GetArena());
}
inline std::string* FieldDescriptorProto::release_type_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_type_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.type_name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.type_name_.IsDefault()) {
          _impl_.type_name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.extendee_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& FieldDescriptorProto::extendee() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.extendee_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
}
inline std::string* FieldDescriptorProto::mutable_extendee() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.extendee_.Get();
}
inline void FieldDescriptorProto::_internal_set_extendee(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.extendee_.Set(value, GetArena());
}
inline std::string* FieldDescriptorProto::_internal_mutable_extendee() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.extendee_.Mutable( GetArena());
}
inline std::string* FieldDescriptorProto::release_extendee() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_extendee(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.extendee_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.extendee_.IsDefault()) {
          _impl_.extendee_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.default_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const std::string& FieldDescriptorProto::default_value() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.default_value_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
}
inline std::string* FieldDescriptorProto::mutable_default_value() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.default_value_.Get();
}
inline void FieldDescriptorProto::_internal_set_default_value(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.default_value_.Set(value, GetArena());
}
inline std::string* FieldDescriptorProto::_internal_mutable_default_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000008u;
  return _impl_.default_value_.Mutable( GetArena());
}
inline std::string* FieldDescriptorProto::release_default_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_default_value(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.default_value_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.default_value_.IsDefault()) {
          _impl_.default_value_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000080u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
}
inline ::int32_t FieldDescriptorProto::_internal_oneof_index() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.oneof_index_;
}
inline void FieldDescriptorProto::_internal_set_oneof_index(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.json_name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline const std::string& FieldDescriptorProto::json_name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.json_name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name)
}
inline std::string* FieldDescriptorProto::mutable_json_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.json_name_.Get();
}
inline void FieldDescriptorProto::_internal_set_json_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.json_name_.Set(value, GetArena());
}
inline std::string* FieldDescriptorProto::_internal_mutable_json_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000010u;
  return _impl_.json_name_.Mutable( GetArena());
}
inline std::string* FieldDescriptorProto::release_json_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldDescriptorProto::set_allocated_json_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.json_name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.json_name_.IsDefault()) {
          _impl_.json_name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000020u;
}
inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FieldOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FieldOptions&>(::google::protobuf::_FieldOptions_default_instance_);
}
inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
  return _internal_options();
}
inline void FieldDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::FieldOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::FieldOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options)
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000020u;
  ::google::protobuf::FieldOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000020u;
  ::google::protobuf::FieldOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FieldOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::FieldOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000020u;
  ::google::protobuf::FieldOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
  return _msg;
}
inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::FieldOptions*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000100u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional)
}
inline bool FieldDescriptorProto::_internal_proto3_optional() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.proto3_optional_;
}
inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& OneofDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
}
inline std::string* OneofDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void OneofDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* OneofDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* OneofDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void OneofDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::OneofOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::OneofOptions&>(::google::protobuf::_OneofOptions_default_instance_);
}
inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options)
  return _internal_options();
}
inline void OneofDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::OneofOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::OneofOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options)
}
inline ::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::OneofOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::OneofOptions* OneofDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::OneofOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::OneofOptions* OneofDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::OneofOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::OneofOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::OneofOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options)
  return _msg;
}
inline void OneofDescriptorProto::set_allocated_options(::google::protobuf::OneofOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::OneofOptions*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000001u;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
}
inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.start_;
}
inline void EnumDescriptorProto_EnumReservedRange::_internal_set_start(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
}
inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.end_;
}
inline void EnumDescriptorProto_EnumReservedRange::_internal_set_end(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& EnumDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
}
inline std::string* EnumDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void EnumDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* EnumDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* EnumDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void EnumDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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 _internal_value().size();
}
inline int EnumDescriptorProto::value_size() const {
  return _internal_value_size();
}
inline void EnumDescriptorProto::clear_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.value_.Clear();
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
  return _internal_mutable_value()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>* EnumDescriptorProto::mutable_value()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_value();
}
inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
  return _internal_value().Get(index);
}
inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::EnumValueDescriptorProto* _add = _internal_mutable_value()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>& EnumDescriptorProto::value() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
  return _internal_value();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>&
EnumDescriptorProto::_internal_value() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.value_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>*
EnumDescriptorProto::_internal_mutable_value() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::EnumOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::EnumOptions&>(::google::protobuf::_EnumOptions_default_instance_);
}
inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
  return _internal_options();
}
inline void EnumDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::EnumOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::EnumOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options)
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::EnumOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::EnumOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::EnumOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::EnumOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::EnumOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
  return _msg;
}
inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::EnumOptions*>(value);
  // @@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 _internal_reserved_range().size();
}
inline int EnumDescriptorProto::reserved_range_size() const {
  return _internal_reserved_range_size();
}
inline void EnumDescriptorProto::clear_reserved_range() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.reserved_range_.Clear();
}
inline ::google::protobuf::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::mutable_reserved_range(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_range)
  return _internal_mutable_reserved_range()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>* EnumDescriptorProto::mutable_reserved_range()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_range)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_reserved_range();
}
inline const ::google::protobuf::EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto::reserved_range(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_range)
  return _internal_reserved_range().Get(index);
}
inline ::google::protobuf::EnumDescriptorProto_EnumReservedRange* EnumDescriptorProto::add_reserved_range() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::EnumDescriptorProto_EnumReservedRange* _add = _internal_mutable_reserved_range()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_range)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>& EnumDescriptorProto::reserved_range() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_range)
  return _internal_reserved_range();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>&
EnumDescriptorProto::_internal_reserved_range() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.reserved_range_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>*
EnumDescriptorProto::_internal_mutable_reserved_range() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.reserved_range_;
}

// repeated string reserved_name = 5;
inline int EnumDescriptorProto::_internal_reserved_name_size() const {
  return _internal_reserved_name().size();
}
inline int EnumDescriptorProto::reserved_name_size() const {
  return _internal_reserved_name_size();
}
inline void EnumDescriptorProto::clear_reserved_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.reserved_name_.Clear();
}
inline std::string* EnumDescriptorProto::add_reserved_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  std::string* _s = _internal_mutable_reserved_name()->Add();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.EnumDescriptorProto.reserved_name)
  return _s;
}
inline const std::string& EnumDescriptorProto::reserved_name(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.reserved_name)
  return _internal_reserved_name().Get(index);
}
inline std::string* EnumDescriptorProto::mutable_reserved_name(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.reserved_name)
  return _internal_mutable_reserved_name()->Mutable(index);
}
template <typename Arg_, typename... Args_>
inline void EnumDescriptorProto::set_reserved_name(int index, Arg_&& value, Args_... args) {
  ::google::protobuf::internal::AssignToString(
      *_internal_mutable_reserved_name()->Mutable(index),
      std::forward<Arg_>(value), args... );
  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.reserved_name)
}
template <typename Arg_, typename... Args_>
inline void EnumDescriptorProto::add_reserved_name(Arg_&& value, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::internal::AddToRepeatedPtrField(*_internal_mutable_reserved_name(),
                               std::forward<Arg_>(value),
                               args... );
  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.reserved_name)
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
EnumDescriptorProto::reserved_name() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_name)
  return _internal_reserved_name();
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
EnumDescriptorProto::mutable_reserved_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_name)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_reserved_name();
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
EnumDescriptorProto::_internal_reserved_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.reserved_name_;
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
EnumDescriptorProto::_internal_mutable_reserved_name() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& EnumValueDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
}
inline std::string* EnumValueDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void EnumValueDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* EnumValueDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* EnumValueDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void EnumValueDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
}
inline ::int32_t EnumValueDescriptorProto::_internal_number() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.number_;
}
inline void EnumValueDescriptorProto::_internal_set_number(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::EnumValueOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::EnumValueOptions&>(::google::protobuf::_EnumValueOptions_default_instance_);
}
inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
  return _internal_options();
}
inline void EnumValueDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::EnumValueOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::EnumValueOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::EnumValueOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::EnumValueOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::EnumValueOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::EnumValueOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::EnumValueOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
  return _msg;
}
inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::EnumValueOptions*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ServiceDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
}
inline std::string* ServiceDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void ServiceDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* ServiceDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* ServiceDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void ServiceDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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 _internal_method().size();
}
inline int ServiceDescriptorProto::method_size() const {
  return _internal_method_size();
}
inline void ServiceDescriptorProto::clear_method() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.method_.Clear();
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
  return _internal_mutable_method()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>* ServiceDescriptorProto::mutable_method()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_method();
}
inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
  return _internal_method().Get(index);
}
inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::MethodDescriptorProto* _add = _internal_mutable_method()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>& ServiceDescriptorProto::method() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
  return _internal_method();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>&
ServiceDescriptorProto::_internal_method() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.method_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>*
ServiceDescriptorProto::_internal_mutable_method() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::ServiceOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::ServiceOptions&>(::google::protobuf::_ServiceOptions_default_instance_);
}
inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
  return _internal_options();
}
inline void ServiceDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::ServiceOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::ServiceOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options)
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::ServiceOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::ServiceOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::ServiceOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::ServiceOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::ServiceOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
  return _msg;
}
inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::ServiceOptions*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& MethodDescriptorProto::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
}
inline std::string* MethodDescriptorProto::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void MethodDescriptorProto::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* MethodDescriptorProto::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* MethodDescriptorProto::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void MethodDescriptorProto::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.input_type_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& MethodDescriptorProto::input_type() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.input_type_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
}
inline std::string* MethodDescriptorProto::mutable_input_type() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.input_type_.Get();
}
inline void MethodDescriptorProto::_internal_set_input_type(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.input_type_.Set(value, GetArena());
}
inline std::string* MethodDescriptorProto::_internal_mutable_input_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.input_type_.Mutable( GetArena());
}
inline std::string* MethodDescriptorProto::release_input_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void MethodDescriptorProto::set_allocated_input_type(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.input_type_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.input_type_.IsDefault()) {
          _impl_.input_type_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.output_type_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& MethodDescriptorProto::output_type() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.output_type_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
}
inline std::string* MethodDescriptorProto::mutable_output_type() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.output_type_.Get();
}
inline void MethodDescriptorProto::_internal_set_output_type(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.output_type_.Set(value, GetArena());
}
inline std::string* MethodDescriptorProto::_internal_mutable_output_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.output_type_.Mutable( GetArena());
}
inline std::string* MethodDescriptorProto::release_output_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void MethodDescriptorProto::set_allocated_output_type(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.output_type_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.output_type_.IsDefault()) {
          _impl_.output_type_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ != nullptr) _impl_.options_->Clear();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::MethodOptions* p = _impl_.options_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::MethodOptions&>(::google::protobuf::_MethodOptions_default_instance_);
}
inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
  return _internal_options();
}
inline void MethodDescriptorProto::unsafe_arena_set_allocated_options(::google::protobuf::MethodOptions* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.options_);
  }
  _impl_.options_ = reinterpret_cast<::google::protobuf::MethodOptions*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options)
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000008u;
  ::google::protobuf::MethodOptions* released = _impl_.options_;
  _impl_.options_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::unsafe_arena_release_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options)

  _impl_._has_bits_[0] &= ~0x00000008u;
  ::google::protobuf::MethodOptions* temp = _impl_.options_;
  _impl_.options_ = nullptr;
  return temp;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::_internal_mutable_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.options_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::MethodOptions>(GetArena());
    _impl_.options_ = reinterpret_cast<::google::protobuf::MethodOptions*>(p);
  }
  return _impl_.options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000008u;
  ::google::protobuf::MethodOptions* _msg = _internal_mutable_options();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
  return _msg;
}
inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.options_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }

  _impl_.options_ = reinterpret_cast<::google::protobuf::MethodOptions*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000010u;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming)
}
inline bool MethodDescriptorProto::_internal_client_streaming() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.client_streaming_;
}
inline void MethodDescriptorProto::_internal_set_client_streaming(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000020u;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming)
}
inline bool MethodDescriptorProto::_internal_server_streaming() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.server_streaming_;
}
inline void MethodDescriptorProto::_internal_set_server_streaming(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.java_package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FileOptions::java_package() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.java_package_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
}
inline std::string* FileOptions::mutable_java_package() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.java_package_.Get();
}
inline void FileOptions::_internal_set_java_package(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.java_package_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_java_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.java_package_.Mutable( GetArena());
}
inline std::string* FileOptions::release_java_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_java_package(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.java_package_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.java_package_.IsDefault()) {
          _impl_.java_package_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.java_outer_classname_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& FileOptions::java_outer_classname() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.java_outer_classname_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
}
inline std::string* FileOptions::mutable_java_outer_classname() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.java_outer_classname_.Get();
}
inline void FileOptions::_internal_set_java_outer_classname(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.java_outer_classname_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_java_outer_classname() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.java_outer_classname_.Mutable( GetArena());
}
inline std::string* FileOptions::release_java_outer_classname() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_java_outer_classname(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.java_outer_classname_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.java_outer_classname_.IsDefault()) {
          _impl_.java_outer_classname_.Set("", GetArena());
        }
  #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] & 0x00000800u) != 0;
  return value;
}
inline void FileOptions::clear_java_multiple_files() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.java_multiple_files_ = false;
  _impl_._has_bits_[0] &= ~0x00000800u;
}
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);
  _impl_._has_bits_[0] |= 0x00000800u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
}
inline bool FileOptions::_internal_java_multiple_files() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.java_multiple_files_;
}
inline void FileOptions::_internal_set_java_multiple_files(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00001000u) != 0;
  return value;
}
inline void FileOptions::clear_java_generate_equals_and_hash() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.java_generate_equals_and_hash_ = false;
  _impl_._has_bits_[0] &= ~0x00001000u;
}
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);
  _impl_._has_bits_[0] |= 0x00001000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
}
inline bool FileOptions::_internal_java_generate_equals_and_hash() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.java_generate_equals_and_hash_;
}
inline void FileOptions::_internal_set_java_generate_equals_and_hash(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00002000u) != 0;
  return value;
}
inline void FileOptions::clear_java_string_check_utf8() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.java_string_check_utf8_ = false;
  _impl_._has_bits_[0] &= ~0x00002000u;
}
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);
  _impl_._has_bits_[0] |= 0x00002000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
}
inline bool FileOptions::_internal_java_string_check_utf8() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.java_string_check_utf8_;
}
inline void FileOptions::_internal_set_java_string_check_utf8(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.optimize_for_ = 1;
  _impl_._has_bits_[0] &= ~0x00040000u;
}
inline ::google::protobuf::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(::google::protobuf::FileOptions_OptimizeMode value) {
  _internal_set_optimize_for(value);
  _impl_._has_bits_[0] |= 0x00040000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
}
inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FileOptions_OptimizeMode>(_impl_.optimize_for_);
}
inline void FileOptions::_internal_set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.go_package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& FileOptions::go_package() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.go_package_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
}
inline std::string* FileOptions::mutable_go_package() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.go_package_.Get();
}
inline void FileOptions::_internal_set_go_package(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.go_package_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_go_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.go_package_.Mutable( GetArena());
}
inline std::string* FileOptions::release_go_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_go_package(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.go_package_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.go_package_.IsDefault()) {
          _impl_.go_package_.Set("", GetArena());
        }
  #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] & 0x00004000u) != 0;
  return value;
}
inline void FileOptions::clear_cc_generic_services() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.cc_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00004000u;
}
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);
  _impl_._has_bits_[0] |= 0x00004000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
}
inline bool FileOptions::_internal_cc_generic_services() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.cc_generic_services_;
}
inline void FileOptions::_internal_set_cc_generic_services(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00008000u) != 0;
  return value;
}
inline void FileOptions::clear_java_generic_services() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.java_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00008000u;
}
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);
  _impl_._has_bits_[0] |= 0x00008000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
}
inline bool FileOptions::_internal_java_generic_services() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.java_generic_services_;
}
inline void FileOptions::_internal_set_java_generic_services(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00010000u) != 0;
  return value;
}
inline void FileOptions::clear_py_generic_services() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.py_generic_services_ = false;
  _impl_._has_bits_[0] &= ~0x00010000u;
}
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);
  _impl_._has_bits_[0] |= 0x00010000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
}
inline bool FileOptions::_internal_py_generic_services() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.py_generic_services_;
}
inline void FileOptions::_internal_set_py_generic_services(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.py_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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00020000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
}
inline bool FileOptions::_internal_deprecated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_;
}
inline void FileOptions::_internal_set_deprecated(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00080000u;
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
}
inline bool FileOptions::_internal_cc_enable_arenas() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.cc_enable_arenas_;
}
inline void FileOptions::_internal_set_cc_enable_arenas(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.objc_class_prefix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline const std::string& FileOptions::objc_class_prefix() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.objc_class_prefix_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
}
inline std::string* FileOptions::mutable_objc_class_prefix() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.objc_class_prefix_.Get();
}
inline void FileOptions::_internal_set_objc_class_prefix(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.objc_class_prefix_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_objc_class_prefix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000008u;
  return _impl_.objc_class_prefix_.Mutable( GetArena());
}
inline std::string* FileOptions::release_objc_class_prefix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_objc_class_prefix(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.objc_class_prefix_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.objc_class_prefix_.IsDefault()) {
          _impl_.objc_class_prefix_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.csharp_namespace_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline const std::string& FileOptions::csharp_namespace() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.csharp_namespace_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
}
inline std::string* FileOptions::mutable_csharp_namespace() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.csharp_namespace_.Get();
}
inline void FileOptions::_internal_set_csharp_namespace(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000010u;
  _impl_.csharp_namespace_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_csharp_namespace() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000010u;
  return _impl_.csharp_namespace_.Mutable( GetArena());
}
inline std::string* FileOptions::release_csharp_namespace() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_csharp_namespace(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000010u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000010u;
  }
  _impl_.csharp_namespace_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.csharp_namespace_.IsDefault()) {
          _impl_.csharp_namespace_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.swift_prefix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000020u;
}
inline const std::string& FileOptions::swift_prefix() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000020u;
  _impl_.swift_prefix_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.swift_prefix)
}
inline std::string* FileOptions::mutable_swift_prefix() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.swift_prefix_.Get();
}
inline void FileOptions::_internal_set_swift_prefix(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000020u;
  _impl_.swift_prefix_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_swift_prefix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000020u;
  return _impl_.swift_prefix_.Mutable( GetArena());
}
inline std::string* FileOptions::release_swift_prefix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_swift_prefix(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000020u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000020u;
  }
  _impl_.swift_prefix_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.swift_prefix_.IsDefault()) {
          _impl_.swift_prefix_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.php_class_prefix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000040u;
}
inline const std::string& FileOptions::php_class_prefix() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000040u;
  _impl_.php_class_prefix_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix)
}
inline std::string* FileOptions::mutable_php_class_prefix() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.php_class_prefix_.Get();
}
inline void FileOptions::_internal_set_php_class_prefix(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000040u;
  _impl_.php_class_prefix_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_php_class_prefix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000040u;
  return _impl_.php_class_prefix_.Mutable( GetArena());
}
inline std::string* FileOptions::release_php_class_prefix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_php_class_prefix(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000040u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000040u;
  }
  _impl_.php_class_prefix_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.php_class_prefix_.IsDefault()) {
          _impl_.php_class_prefix_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.php_namespace_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000080u;
}
inline const std::string& FileOptions::php_namespace() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000080u;
  _impl_.php_namespace_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
}
inline std::string* FileOptions::mutable_php_namespace() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.php_namespace_.Get();
}
inline void FileOptions::_internal_set_php_namespace(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000080u;
  _impl_.php_namespace_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_php_namespace() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000080u;
  return _impl_.php_namespace_.Mutable( GetArena());
}
inline std::string* FileOptions::release_php_namespace() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_php_namespace(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000080u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000080u;
  }
  _impl_.php_namespace_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.php_namespace_.IsDefault()) {
          _impl_.php_namespace_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.php_metadata_namespace_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000100u;
}
inline const std::string& FileOptions::php_metadata_namespace() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.php_metadata_namespace_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_metadata_namespace)
}
inline std::string* FileOptions::mutable_php_metadata_namespace() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.php_metadata_namespace_.Get();
}
inline void FileOptions::_internal_set_php_metadata_namespace(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000100u;
  _impl_.php_metadata_namespace_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000100u;
  return _impl_.php_metadata_namespace_.Mutable( GetArena());
}
inline std::string* FileOptions::release_php_metadata_namespace() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_php_metadata_namespace(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000100u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000100u;
  }
  _impl_.php_metadata_namespace_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.php_metadata_namespace_.IsDefault()) {
          _impl_.php_metadata_namespace_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.ruby_package_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000200u;
}
inline const std::string& FileOptions::ruby_package() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000200u;
  _impl_.ruby_package_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.ruby_package)
}
inline std::string* FileOptions::mutable_ruby_package() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.ruby_package_.Get();
}
inline void FileOptions::_internal_set_ruby_package(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000200u;
  _impl_.ruby_package_.Set(value, GetArena());
}
inline std::string* FileOptions::_internal_mutable_ruby_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000200u;
  return _impl_.ruby_package_.Mutable( GetArena());
}
inline std::string* FileOptions::release_ruby_package() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FileOptions::set_allocated_ruby_package(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000200u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000200u;
  }
  _impl_.ruby_package_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.ruby_package_.IsDefault()) {
          _impl_.ruby_package_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.ruby_package)
}

// optional .google.protobuf.FeatureSet features = 50;
inline bool FileOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000400u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void FileOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000400u;
}
inline const ::google::protobuf::FeatureSet& FileOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& FileOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.features)
  return _internal_features();
}
inline void FileOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000400u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000400u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.features)
}
inline ::google::protobuf::FeatureSet* FileOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000400u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* FileOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.features)

  _impl_._has_bits_[0] &= ~0x00000400u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* FileOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* FileOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000400u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.features)
  return _msg;
}
inline void FileOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000400u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000400u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.features)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FileOptions::_internal_uninterpreted_option_size() const {
  return _internal_uninterpreted_option().size();
}
inline int FileOptions::uninterpreted_option_size() const {
  return _internal_uninterpreted_option_size();
}
inline void FileOptions::clear_uninterpreted_option() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.uninterpreted_option_.Clear();
}
inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
  return _internal_mutable_uninterpreted_option()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* FileOptions::mutable_uninterpreted_option()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_uninterpreted_option();
}
inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
  return _internal_uninterpreted_option().Get(index);
}
inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::UninterpretedOption* _add = _internal_mutable_uninterpreted_option()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& FileOptions::uninterpreted_option() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
  return _internal_uninterpreted_option();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>&
FileOptions::_internal_uninterpreted_option() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>*
FileOptions::_internal_mutable_uninterpreted_option() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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] & 0x00000002u) != 0;
  return value;
}
inline void MessageOptions::clear_message_set_wire_format() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.message_set_wire_format_ = false;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
}
inline bool MessageOptions::_internal_message_set_wire_format() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.message_set_wire_format_;
}
inline void MessageOptions::_internal_set_message_set_wire_format(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00000004u) != 0;
  return value;
}
inline void MessageOptions::clear_no_standard_descriptor_accessor() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.no_standard_descriptor_accessor_ = false;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
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);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
}
inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.no_standard_descriptor_accessor_;
}
inline void MessageOptions::_internal_set_no_standard_descriptor_accessor(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.no_standard_descriptor_accessor_ = value;
}

// optional bool deprecated = 3 [default = false];
inline bool MessageOptions::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline void MessageOptions::clear_deprecated() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
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);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
}
inline bool MessageOptions::_internal_deprecated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_;
}
inline void MessageOptions::_internal_set_deprecated(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_ = value;
}

// optional bool map_entry = 7;
inline bool MessageOptions::has_map_entry() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void MessageOptions::clear_map_entry() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.map_entry_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
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);
  _impl_._has_bits_[0] |= 0x00000010u;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry)
}
inline bool MessageOptions::_internal_map_entry() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.map_entry_;
}
inline void MessageOptions::_internal_set_map_entry(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00000020u) != 0;
  return value;
}
inline void MessageOptions::clear_deprecated_legacy_json_field_conflicts() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_legacy_json_field_conflicts_ = false;
  _impl_._has_bits_[0] &= ~0x00000020u;
}
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);
  _impl_._has_bits_[0] |= 0x00000020u;
  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts)
}
inline bool MessageOptions::_internal_deprecated_legacy_json_field_conflicts() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_legacy_json_field_conflicts_;
}
inline void MessageOptions::_internal_set_deprecated_legacy_json_field_conflicts(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_legacy_json_field_conflicts_ = value;
}

// optional .google.protobuf.FeatureSet features = 12;
inline bool MessageOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void MessageOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& MessageOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& MessageOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.features)
  return _internal_features();
}
inline void MessageOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MessageOptions.features)
}
inline ::google::protobuf::FeatureSet* MessageOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* MessageOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.MessageOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* MessageOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* MessageOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.features)
  return _msg;
}
inline void MessageOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MessageOptions.features)
}

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

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

// FieldOptions_EditionDefault

// optional .google.protobuf.Edition edition = 3;
inline bool FieldOptions_EditionDefault::has_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void FieldOptions_EditionDefault::clear_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::google::protobuf::Edition FieldOptions_EditionDefault::edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.EditionDefault.edition)
  return _internal_edition();
}
inline void FieldOptions_EditionDefault::set_edition(::google::protobuf::Edition value) {
  _internal_set_edition(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.EditionDefault.edition)
}
inline ::google::protobuf::Edition FieldOptions_EditionDefault::_internal_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.edition_);
}
inline void FieldOptions_EditionDefault::_internal_set_edition(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.edition_ = value;
}

// optional string value = 2;
inline bool FieldOptions_EditionDefault::has_value() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void FieldOptions_EditionDefault::clear_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FieldOptions_EditionDefault::value() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.EditionDefault.value)
  return _internal_value();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldOptions_EditionDefault::set_value(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.value_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.EditionDefault.value)
}
inline std::string* FieldOptions_EditionDefault::mutable_value() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  std::string* _s = _internal_mutable_value();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.EditionDefault.value)
  return _s;
}
inline const std::string& FieldOptions_EditionDefault::_internal_value() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.value_.Get();
}
inline void FieldOptions_EditionDefault::_internal_set_value(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.value_.Set(value, GetArena());
}
inline std::string* FieldOptions_EditionDefault::_internal_mutable_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.value_.Mutable( GetArena());
}
inline std::string* FieldOptions_EditionDefault::release_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FieldOptions.EditionDefault.value)
  if ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.value_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.value_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldOptions_EditionDefault::set_allocated_value(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.value_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.value_.IsDefault()) {
          _impl_.value_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.EditionDefault.value)
}

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

// FieldOptions_FeatureSupport

// optional .google.protobuf.Edition edition_introduced = 1;
inline bool FieldOptions_FeatureSupport::has_edition_introduced() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void FieldOptions_FeatureSupport::clear_edition_introduced() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_introduced_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::google::protobuf::Edition FieldOptions_FeatureSupport::edition_introduced() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.FeatureSupport.edition_introduced)
  return _internal_edition_introduced();
}
inline void FieldOptions_FeatureSupport::set_edition_introduced(::google::protobuf::Edition value) {
  _internal_set_edition_introduced(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.FeatureSupport.edition_introduced)
}
inline ::google::protobuf::Edition FieldOptions_FeatureSupport::_internal_edition_introduced() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.edition_introduced_);
}
inline void FieldOptions_FeatureSupport::_internal_set_edition_introduced(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.edition_introduced_ = value;
}

// optional .google.protobuf.Edition edition_deprecated = 2;
inline bool FieldOptions_FeatureSupport::has_edition_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void FieldOptions_FeatureSupport::clear_edition_deprecated() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_deprecated_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::google::protobuf::Edition FieldOptions_FeatureSupport::edition_deprecated() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.FeatureSupport.edition_deprecated)
  return _internal_edition_deprecated();
}
inline void FieldOptions_FeatureSupport::set_edition_deprecated(::google::protobuf::Edition value) {
  _internal_set_edition_deprecated(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.FeatureSupport.edition_deprecated)
}
inline ::google::protobuf::Edition FieldOptions_FeatureSupport::_internal_edition_deprecated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.edition_deprecated_);
}
inline void FieldOptions_FeatureSupport::_internal_set_edition_deprecated(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.edition_deprecated_ = value;
}

// optional string deprecation_warning = 3;
inline bool FieldOptions_FeatureSupport::has_deprecation_warning() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void FieldOptions_FeatureSupport::clear_deprecation_warning() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecation_warning_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& FieldOptions_FeatureSupport::deprecation_warning() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.FeatureSupport.deprecation_warning)
  return _internal_deprecation_warning();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void FieldOptions_FeatureSupport::set_deprecation_warning(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.deprecation_warning_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.FeatureSupport.deprecation_warning)
}
inline std::string* FieldOptions_FeatureSupport::mutable_deprecation_warning() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  std::string* _s = _internal_mutable_deprecation_warning();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.FeatureSupport.deprecation_warning)
  return _s;
}
inline const std::string& FieldOptions_FeatureSupport::_internal_deprecation_warning() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecation_warning_.Get();
}
inline void FieldOptions_FeatureSupport::_internal_set_deprecation_warning(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.deprecation_warning_.Set(value, GetArena());
}
inline std::string* FieldOptions_FeatureSupport::_internal_mutable_deprecation_warning() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.deprecation_warning_.Mutable( GetArena());
}
inline std::string* FieldOptions_FeatureSupport::release_deprecation_warning() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FieldOptions.FeatureSupport.deprecation_warning)
  if ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* released = _impl_.deprecation_warning_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.deprecation_warning_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void FieldOptions_FeatureSupport::set_allocated_deprecation_warning(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.deprecation_warning_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.deprecation_warning_.IsDefault()) {
          _impl_.deprecation_warning_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.FeatureSupport.deprecation_warning)
}

// optional .google.protobuf.Edition edition_removed = 4;
inline bool FieldOptions_FeatureSupport::has_edition_removed() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline void FieldOptions_FeatureSupport::clear_edition_removed() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_removed_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::google::protobuf::Edition FieldOptions_FeatureSupport::edition_removed() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.FeatureSupport.edition_removed)
  return _internal_edition_removed();
}
inline void FieldOptions_FeatureSupport::set_edition_removed(::google::protobuf::Edition value) {
  _internal_set_edition_removed(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.FeatureSupport.edition_removed)
}
inline ::google::protobuf::Edition FieldOptions_FeatureSupport::_internal_edition_removed() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.edition_removed_);
}
inline void FieldOptions_FeatureSupport::_internal_set_edition_removed(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.edition_removed_ = value;
}

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

// FieldOptions

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

// optional bool packed = 2;
inline bool FieldOptions::has_packed() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void FieldOptions::clear_packed() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.packed_ = false;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
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);
  _impl_._has_bits_[0] |= 0x00000010u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
}
inline bool FieldOptions::_internal_packed() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.packed_;
}
inline void FieldOptions::_internal_set_packed(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00000008u) != 0;
  return value;
}
inline void FieldOptions::clear_jstype() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.jstype_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype)
  return _internal_jstype();
}
inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) {
  _internal_set_jstype(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype)
}
inline ::google::protobuf::FieldOptions_JSType FieldOptions::_internal_jstype() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FieldOptions_JSType>(_impl_.jstype_);
}
inline void FieldOptions::_internal_set_jstype(::google::protobuf::FieldOptions_JSType value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FieldOptions_JSType_IsValid(value));
  _impl_.jstype_ = value;
}

// optional bool lazy = 5 [default = false];
inline bool FieldOptions::has_lazy() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline void FieldOptions::clear_lazy() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.lazy_ = false;
  _impl_._has_bits_[0] &= ~0x00000020u;
}
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);
  _impl_._has_bits_[0] |= 0x00000020u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
}
inline bool FieldOptions::_internal_lazy() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.lazy_;
}
inline void FieldOptions::_internal_set_lazy(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.lazy_ = value;
}

// optional bool unverified_lazy = 15 [default = false];
inline bool FieldOptions::has_unverified_lazy() const {
  bool value = (_impl_._has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline void FieldOptions::clear_unverified_lazy() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.unverified_lazy_ = false;
  _impl_._has_bits_[0] &= ~0x00000040u;
}
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);
  _impl_._has_bits_[0] |= 0x00000040u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.unverified_lazy)
}
inline bool FieldOptions::_internal_unverified_lazy() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.unverified_lazy_;
}
inline void FieldOptions::_internal_set_unverified_lazy(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.unverified_lazy_ = value;
}

// optional bool deprecated = 3 [default = false];
inline bool FieldOptions::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline void FieldOptions::clear_deprecated() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000080u;
}
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);
  _impl_._has_bits_[0] |= 0x00000080u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
}
inline bool FieldOptions::_internal_deprecated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_;
}
inline void FieldOptions::_internal_set_deprecated(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_ = value;
}

// optional bool weak = 10 [default = false];
inline bool FieldOptions::has_weak() const {
  bool value = (_impl_._has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline void FieldOptions::clear_weak() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.weak_ = false;
  _impl_._has_bits_[0] &= ~0x00000100u;
}
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);
  _impl_._has_bits_[0] |= 0x00000100u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
}
inline bool FieldOptions::_internal_weak() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.weak_;
}
inline void FieldOptions::_internal_set_weak(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.weak_ = value;
}

// optional bool debug_redact = 16 [default = false];
inline bool FieldOptions::has_debug_redact() const {
  bool value = (_impl_._has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline void FieldOptions::clear_debug_redact() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.debug_redact_ = false;
  _impl_._has_bits_[0] &= ~0x00000200u;
}
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);
  _impl_._has_bits_[0] |= 0x00000200u;
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.debug_redact)
}
inline bool FieldOptions::_internal_debug_redact() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.debug_redact_;
}
inline void FieldOptions::_internal_set_debug_redact(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.debug_redact_ = value;
}

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

// repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19;
inline int FieldOptions::_internal_targets_size() const {
  return _internal_targets().size();
}
inline int FieldOptions::targets_size() const {
  return _internal_targets_size();
}
inline void FieldOptions::clear_targets() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.targets_.Clear();
}
inline ::google::protobuf::FieldOptions_OptionTargetType FieldOptions::targets(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.targets)
  return static_cast<::google::protobuf::FieldOptions_OptionTargetType>(_internal_targets().Get(index));
}
inline void FieldOptions::set_targets(int index, ::google::protobuf::FieldOptions_OptionTargetType value) {
  assert(::google::protobuf::FieldOptions_OptionTargetType_IsValid(value));
  _internal_mutable_targets()->Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.targets)
}
inline void FieldOptions::add_targets(::google::protobuf::FieldOptions_OptionTargetType value) {
  assert(::google::protobuf::FieldOptions_OptionTargetType_IsValid(value));
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _internal_mutable_targets()->Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.targets)
}
inline const ::google::protobuf::RepeatedField<int>& FieldOptions::targets() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.targets)
  return _internal_targets();
}
inline ::google::protobuf::RepeatedField<int>* FieldOptions::mutable_targets()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.targets)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_targets();
}
inline const ::google::protobuf::RepeatedField<int>& FieldOptions::_internal_targets()
    const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.targets_;
}
inline ::google::protobuf::RepeatedField<int>* FieldOptions::_internal_mutable_targets() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.targets_;
}

// repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20;
inline int FieldOptions::_internal_edition_defaults_size() const {
  return _internal_edition_defaults().size();
}
inline int FieldOptions::edition_defaults_size() const {
  return _internal_edition_defaults_size();
}
inline void FieldOptions::clear_edition_defaults() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_defaults_.Clear();
}
inline ::google::protobuf::FieldOptions_EditionDefault* FieldOptions::mutable_edition_defaults(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.edition_defaults)
  return _internal_mutable_edition_defaults()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>* FieldOptions::mutable_edition_defaults()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.edition_defaults)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_edition_defaults();
}
inline const ::google::protobuf::FieldOptions_EditionDefault& FieldOptions::edition_defaults(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.edition_defaults)
  return _internal_edition_defaults().Get(index);
}
inline ::google::protobuf::FieldOptions_EditionDefault* FieldOptions::add_edition_defaults() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::FieldOptions_EditionDefault* _add = _internal_mutable_edition_defaults()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.edition_defaults)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>& FieldOptions::edition_defaults() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.edition_defaults)
  return _internal_edition_defaults();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>&
FieldOptions::_internal_edition_defaults() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.edition_defaults_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>*
FieldOptions::_internal_mutable_edition_defaults() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.edition_defaults_;
}

// optional .google.protobuf.FeatureSet features = 21;
inline bool FieldOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void FieldOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& FieldOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& FieldOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.features)
  return _internal_features();
}
inline void FieldOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldOptions.features)
}
inline ::google::protobuf::FeatureSet* FieldOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* FieldOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FieldOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* FieldOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* FieldOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.features)
  return _msg;
}
inline void FieldOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.features)
}

// optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22;
inline bool FieldOptions::has_feature_support() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.feature_support_ != nullptr);
  return value;
}
inline void FieldOptions::clear_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.feature_support_ != nullptr) _impl_.feature_support_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::FieldOptions_FeatureSupport& FieldOptions::_internal_feature_support() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FieldOptions_FeatureSupport* p = _impl_.feature_support_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FieldOptions_FeatureSupport&>(::google::protobuf::_FieldOptions_FeatureSupport_default_instance_);
}
inline const ::google::protobuf::FieldOptions_FeatureSupport& FieldOptions::feature_support() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.feature_support)
  return _internal_feature_support();
}
inline void FieldOptions::unsafe_arena_set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.feature_support_);
  }
  _impl_.feature_support_ = reinterpret_cast<::google::protobuf::FieldOptions_FeatureSupport*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldOptions.feature_support)
}
inline ::google::protobuf::FieldOptions_FeatureSupport* FieldOptions::release_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::FieldOptions_FeatureSupport* released = _impl_.feature_support_;
  _impl_.feature_support_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FieldOptions_FeatureSupport* FieldOptions::unsafe_arena_release_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FieldOptions.feature_support)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::FieldOptions_FeatureSupport* temp = _impl_.feature_support_;
  _impl_.feature_support_ = nullptr;
  return temp;
}
inline ::google::protobuf::FieldOptions_FeatureSupport* FieldOptions::_internal_mutable_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.feature_support_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FieldOptions_FeatureSupport>(GetArena());
    _impl_.feature_support_ = reinterpret_cast<::google::protobuf::FieldOptions_FeatureSupport*>(p);
  }
  return _impl_.feature_support_;
}
inline ::google::protobuf::FieldOptions_FeatureSupport* FieldOptions::mutable_feature_support() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::FieldOptions_FeatureSupport* _msg = _internal_mutable_feature_support();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.feature_support)
  return _msg;
}
inline void FieldOptions::set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.feature_support_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.feature_support_ = reinterpret_cast<::google::protobuf::FieldOptions_FeatureSupport*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.feature_support)
}

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

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

// OneofOptions

// optional .google.protobuf.FeatureSet features = 1;
inline bool OneofOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void OneofOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& OneofOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& OneofOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.features)
  return _internal_features();
}
inline void OneofOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofOptions.features)
}
inline ::google::protobuf::FeatureSet* OneofOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* OneofOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.OneofOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* OneofOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* OneofOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.features)
  return _msg;
}
inline void OneofOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofOptions.features)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int OneofOptions::_internal_uninterpreted_option_size() const {
  return _internal_uninterpreted_option().size();
}
inline int OneofOptions::uninterpreted_option_size() const {
  return _internal_uninterpreted_option_size();
}
inline void OneofOptions::clear_uninterpreted_option() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.uninterpreted_option_.Clear();
}
inline ::google::protobuf::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option)
  return _internal_mutable_uninterpreted_option()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* OneofOptions::mutable_uninterpreted_option()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_uninterpreted_option();
}
inline const ::google::protobuf::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option)
  return _internal_uninterpreted_option().Get(index);
}
inline ::google::protobuf::UninterpretedOption* OneofOptions::add_uninterpreted_option() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::UninterpretedOption* _add = _internal_mutable_uninterpreted_option()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& OneofOptions::uninterpreted_option() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option)
  return _internal_uninterpreted_option();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>&
OneofOptions::_internal_uninterpreted_option() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>*
OneofOptions::_internal_mutable_uninterpreted_option() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.uninterpreted_option_;
}

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

// EnumOptions

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

// optional bool deprecated = 3 [default = false];
inline bool EnumOptions::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void EnumOptions::clear_deprecated() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
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);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
}
inline bool EnumOptions::_internal_deprecated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_;
}
inline void EnumOptions::_internal_set_deprecated(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00000008u) != 0;
  return value;
}
inline void EnumOptions::clear_deprecated_legacy_json_field_conflicts() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_legacy_json_field_conflicts_ = false;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
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);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts)
}
inline bool EnumOptions::_internal_deprecated_legacy_json_field_conflicts() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_legacy_json_field_conflicts_;
}
inline void EnumOptions::_internal_set_deprecated_legacy_json_field_conflicts(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_legacy_json_field_conflicts_ = value;
}

// optional .google.protobuf.FeatureSet features = 7;
inline bool EnumOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void EnumOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& EnumOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& EnumOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.features)
  return _internal_features();
}
inline void EnumOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumOptions.features)
}
inline ::google::protobuf::FeatureSet* EnumOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* EnumOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.EnumOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* EnumOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* EnumOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.features)
  return _msg;
}
inline void EnumOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumOptions.features)
}

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

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

// EnumValueOptions

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

// optional .google.protobuf.FeatureSet features = 2;
inline bool EnumValueOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void EnumValueOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& EnumValueOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& EnumValueOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.features)
  return _internal_features();
}
inline void EnumValueOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueOptions.features)
}
inline ::google::protobuf::FeatureSet* EnumValueOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* EnumValueOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValueOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* EnumValueOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* EnumValueOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.features)
  return _msg;
}
inline void EnumValueOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueOptions.features)
}

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

// optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4;
inline bool EnumValueOptions::has_feature_support() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.feature_support_ != nullptr);
  return value;
}
inline void EnumValueOptions::clear_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.feature_support_ != nullptr) _impl_.feature_support_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::FieldOptions_FeatureSupport& EnumValueOptions::_internal_feature_support() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FieldOptions_FeatureSupport* p = _impl_.feature_support_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FieldOptions_FeatureSupport&>(::google::protobuf::_FieldOptions_FeatureSupport_default_instance_);
}
inline const ::google::protobuf::FieldOptions_FeatureSupport& EnumValueOptions::feature_support() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.feature_support)
  return _internal_feature_support();
}
inline void EnumValueOptions::unsafe_arena_set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.feature_support_);
  }
  _impl_.feature_support_ = reinterpret_cast<::google::protobuf::FieldOptions_FeatureSupport*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueOptions.feature_support)
}
inline ::google::protobuf::FieldOptions_FeatureSupport* EnumValueOptions::release_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::FieldOptions_FeatureSupport* released = _impl_.feature_support_;
  _impl_.feature_support_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FieldOptions_FeatureSupport* EnumValueOptions::unsafe_arena_release_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.EnumValueOptions.feature_support)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::FieldOptions_FeatureSupport* temp = _impl_.feature_support_;
  _impl_.feature_support_ = nullptr;
  return temp;
}
inline ::google::protobuf::FieldOptions_FeatureSupport* EnumValueOptions::_internal_mutable_feature_support() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.feature_support_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FieldOptions_FeatureSupport>(GetArena());
    _impl_.feature_support_ = reinterpret_cast<::google::protobuf::FieldOptions_FeatureSupport*>(p);
  }
  return _impl_.feature_support_;
}
inline ::google::protobuf::FieldOptions_FeatureSupport* EnumValueOptions::mutable_feature_support() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::FieldOptions_FeatureSupport* _msg = _internal_mutable_feature_support();
  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.feature_support)
  return _msg;
}
inline void EnumValueOptions::set_allocated_feature_support(::google::protobuf::FieldOptions_FeatureSupport* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.feature_support_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.feature_support_ = reinterpret_cast<::google::protobuf::FieldOptions_FeatureSupport*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueOptions.feature_support)
}

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

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

// ServiceOptions

// optional .google.protobuf.FeatureSet features = 34;
inline bool ServiceOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void ServiceOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& ServiceOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& ServiceOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.features)
  return _internal_features();
}
inline void ServiceOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceOptions.features)
}
inline ::google::protobuf::FeatureSet* ServiceOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* ServiceOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.ServiceOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* ServiceOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* ServiceOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.features)
  return _msg;
}
inline void ServiceOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceOptions.features)
}

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

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

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

// MethodOptions

// optional bool deprecated = 33 [default = false];
inline bool MethodOptions::has_deprecated() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void MethodOptions::clear_deprecated() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.deprecated_ = false;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
}
inline bool MethodOptions::_internal_deprecated() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.deprecated_;
}
inline void MethodOptions::_internal_set_deprecated(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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] & 0x00000004u) != 0;
  return value;
}
inline void MethodOptions::clear_idempotency_level() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.idempotency_level_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::google::protobuf::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(::google::protobuf::MethodOptions_IdempotencyLevel value) {
  _internal_set_idempotency_level(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level)
}
inline ::google::protobuf::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::MethodOptions_IdempotencyLevel>(_impl_.idempotency_level_);
}
inline void MethodOptions::_internal_set_idempotency_level(::google::protobuf::MethodOptions_IdempotencyLevel value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(value));
  _impl_.idempotency_level_ = value;
}

// optional .google.protobuf.FeatureSet features = 35;
inline bool MethodOptions::has_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.features_ != nullptr);
  return value;
}
inline void MethodOptions::clear_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ != nullptr) _impl_.features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& MethodOptions::_internal_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& MethodOptions::features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.features)
  return _internal_features();
}
inline void MethodOptions::unsafe_arena_set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.features_);
  }
  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodOptions.features)
}
inline ::google::protobuf::FeatureSet* MethodOptions::release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.features_;
  _impl_.features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* MethodOptions::unsafe_arena_release_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.MethodOptions.features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.features_;
  _impl_.features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* MethodOptions::_internal_mutable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.features_;
}
inline ::google::protobuf::FeatureSet* MethodOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.features)
  return _msg;
}
inline void MethodOptions::set_allocated_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodOptions.features)
}

// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int MethodOptions::_internal_uninterpreted_option_size() const {
  return _internal_uninterpreted_option().size();
}
inline int MethodOptions::uninterpreted_option_size() const {
  return _internal_uninterpreted_option_size();
}
inline void MethodOptions::clear_uninterpreted_option() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.uninterpreted_option_.Clear();
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
  return _internal_mutable_uninterpreted_option()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* MethodOptions::mutable_uninterpreted_option()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_uninterpreted_option();
}
inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
  return _internal_uninterpreted_option().Get(index);
}
inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::UninterpretedOption* _add = _internal_mutable_uninterpreted_option()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& MethodOptions::uninterpreted_option() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
  return _internal_uninterpreted_option();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>&
MethodOptions::_internal_uninterpreted_option() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.uninterpreted_option_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>*
MethodOptions::_internal_mutable_uninterpreted_option() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_part_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& UninterpretedOption_NamePart::name_part() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_part_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
}
inline std::string* UninterpretedOption_NamePart::mutable_name_part() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_part_.Get();
}
inline void UninterpretedOption_NamePart::_internal_set_name_part(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_part_.Set(value, GetArena());
}
inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_part_.Mutable( GetArena());
}
inline std::string* UninterpretedOption_NamePart::release_name_part() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_part_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_part_.IsDefault()) {
          _impl_.name_part_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
}
inline bool UninterpretedOption_NamePart::_internal_is_extension() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.is_extension_;
}
inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.is_extension_ = value;
}

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

// UninterpretedOption

// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
inline int UninterpretedOption::_internal_name_size() const {
  return _internal_name().size();
}
inline int UninterpretedOption::name_size() const {
  return _internal_name_size();
}
inline void UninterpretedOption::clear_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.Clear();
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
  return _internal_mutable_name()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>* UninterpretedOption::mutable_name()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_name();
}
inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
  return _internal_name().Get(index);
}
inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::UninterpretedOption_NamePart* _add = _internal_mutable_name()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>& UninterpretedOption::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
  return _internal_name();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>&
UninterpretedOption::_internal_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>*
UninterpretedOption::_internal_mutable_name() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.identifier_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& UninterpretedOption::identifier_value() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.identifier_value_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
}
inline std::string* UninterpretedOption::mutable_identifier_value() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.identifier_value_.Get();
}
inline void UninterpretedOption::_internal_set_identifier_value(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.identifier_value_.Set(value, GetArena());
}
inline std::string* UninterpretedOption::_internal_mutable_identifier_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.identifier_value_.Mutable( GetArena());
}
inline std::string* UninterpretedOption::release_identifier_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption::set_allocated_identifier_value(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.identifier_value_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.identifier_value_.IsDefault()) {
          _impl_.identifier_value_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
}
inline ::uint64_t UninterpretedOption::_internal_positive_int_value() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.positive_int_value_;
}
inline void UninterpretedOption::_internal_set_positive_int_value(::uint64_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000010u;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
}
inline ::int64_t UninterpretedOption::_internal_negative_int_value() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.negative_int_value_;
}
inline void UninterpretedOption::_internal_set_negative_int_value(::int64_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000020u;
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
}
inline double UninterpretedOption::_internal_double_value() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.double_value_;
}
inline void UninterpretedOption::_internal_set_double_value(double value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.string_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& UninterpretedOption::string_value() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.string_value_.SetBytes(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
}
inline std::string* UninterpretedOption::mutable_string_value() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.string_value_.Get();
}
inline void UninterpretedOption::_internal_set_string_value(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.string_value_.Set(value, GetArena());
}
inline std::string* UninterpretedOption::_internal_mutable_string_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.string_value_.Mutable( GetArena());
}
inline std::string* UninterpretedOption::release_string_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption::set_allocated_string_value(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.string_value_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.string_value_.IsDefault()) {
          _impl_.string_value_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.aggregate_value_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& UninterpretedOption::aggregate_value() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.aggregate_value_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
}
inline std::string* UninterpretedOption::mutable_aggregate_value() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.aggregate_value_.Get();
}
inline void UninterpretedOption::_internal_set_aggregate_value(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.aggregate_value_.Set(value, GetArena());
}
inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.aggregate_value_.Mutable( GetArena());
}
inline std::string* UninterpretedOption::release_aggregate_value() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void UninterpretedOption::set_allocated_aggregate_value(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.aggregate_value_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.aggregate_value_.IsDefault()) {
          _impl_.aggregate_value_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
}

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

// FeatureSet

// optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool FeatureSet::has_field_presence() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void FeatureSet::clear_field_presence() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.field_presence_ = 0;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::field_presence() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.field_presence)
  return _internal_field_presence();
}
inline void FeatureSet::set_field_presence(::google::protobuf::FeatureSet_FieldPresence value) {
  _internal_set_field_presence(value);
  _impl_._has_bits_[0] |= 0x00000001u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.field_presence)
}
inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::_internal_field_presence() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FeatureSet_FieldPresence>(_impl_.field_presence_);
}
inline void FeatureSet::_internal_set_field_presence(::google::protobuf::FeatureSet_FieldPresence value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FeatureSet_FieldPresence_IsValid(value));
  _impl_.field_presence_ = value;
}

// optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool FeatureSet::has_enum_type() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void FeatureSet::clear_enum_type() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.enum_type_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::google::protobuf::FeatureSet_EnumType FeatureSet::enum_type() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.enum_type)
  return _internal_enum_type();
}
inline void FeatureSet::set_enum_type(::google::protobuf::FeatureSet_EnumType value) {
  _internal_set_enum_type(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.enum_type)
}
inline ::google::protobuf::FeatureSet_EnumType FeatureSet::_internal_enum_type() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FeatureSet_EnumType>(_impl_.enum_type_);
}
inline void FeatureSet::_internal_set_enum_type(::google::protobuf::FeatureSet_EnumType value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FeatureSet_EnumType_IsValid(value));
  _impl_.enum_type_ = value;
}

// optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool FeatureSet::has_repeated_field_encoding() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void FeatureSet::clear_repeated_field_encoding() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.repeated_field_encoding_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::repeated_field_encoding() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.repeated_field_encoding)
  return _internal_repeated_field_encoding();
}
inline void FeatureSet::set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value) {
  _internal_set_repeated_field_encoding(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.repeated_field_encoding)
}
inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::_internal_repeated_field_encoding() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FeatureSet_RepeatedFieldEncoding>(_impl_.repeated_field_encoding_);
}
inline void FeatureSet::_internal_set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FeatureSet_RepeatedFieldEncoding_IsValid(value));
  _impl_.repeated_field_encoding_ = value;
}

// optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool FeatureSet::has_utf8_validation() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline void FeatureSet::clear_utf8_validation() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.utf8_validation_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::google::protobuf::FeatureSet_Utf8Validation FeatureSet::utf8_validation() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.utf8_validation)
  return _internal_utf8_validation();
}
inline void FeatureSet::set_utf8_validation(::google::protobuf::FeatureSet_Utf8Validation value) {
  _internal_set_utf8_validation(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.utf8_validation)
}
inline ::google::protobuf::FeatureSet_Utf8Validation FeatureSet::_internal_utf8_validation() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FeatureSet_Utf8Validation>(_impl_.utf8_validation_);
}
inline void FeatureSet::_internal_set_utf8_validation(::google::protobuf::FeatureSet_Utf8Validation value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FeatureSet_Utf8Validation_IsValid(value));
  _impl_.utf8_validation_ = value;
}

// optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool FeatureSet::has_message_encoding() const {
  bool value = (_impl_._has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline void FeatureSet::clear_message_encoding() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.message_encoding_ = 0;
  _impl_._has_bits_[0] &= ~0x00000010u;
}
inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::message_encoding() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.message_encoding)
  return _internal_message_encoding();
}
inline void FeatureSet::set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value) {
  _internal_set_message_encoding(value);
  _impl_._has_bits_[0] |= 0x00000010u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.message_encoding)
}
inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::_internal_message_encoding() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FeatureSet_MessageEncoding>(_impl_.message_encoding_);
}
inline void FeatureSet::_internal_set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FeatureSet_MessageEncoding_IsValid(value));
  _impl_.message_encoding_ = value;
}

// optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
inline bool FeatureSet::has_json_format() const {
  bool value = (_impl_._has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline void FeatureSet::clear_json_format() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.json_format_ = 0;
  _impl_._has_bits_[0] &= ~0x00000020u;
}
inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::json_format() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSet.json_format)
  return _internal_json_format();
}
inline void FeatureSet::set_json_format(::google::protobuf::FeatureSet_JsonFormat value) {
  _internal_set_json_format(value);
  _impl_._has_bits_[0] |= 0x00000020u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.json_format)
}
inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::_internal_json_format() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::FeatureSet_JsonFormat>(_impl_.json_format_);
}
inline void FeatureSet::_internal_set_json_format(::google::protobuf::FeatureSet_JsonFormat value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::FeatureSet_JsonFormat_IsValid(value));
  _impl_.json_format_ = value;
}

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

// FeatureSetDefaults_FeatureSetEditionDefault

// optional .google.protobuf.Edition edition = 3;
inline bool FeatureSetDefaults_FeatureSetEditionDefault::has_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::clear_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::google::protobuf::Edition FeatureSetDefaults_FeatureSetEditionDefault::edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition)
  return _internal_edition();
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::set_edition(::google::protobuf::Edition value) {
  _internal_set_edition(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition)
}
inline ::google::protobuf::Edition FeatureSetDefaults_FeatureSetEditionDefault::_internal_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.edition_);
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::_internal_set_edition(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.edition_ = value;
}

// optional .google.protobuf.FeatureSet overridable_features = 4;
inline bool FeatureSetDefaults_FeatureSetEditionDefault::has_overridable_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.overridable_features_ != nullptr);
  return value;
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::clear_overridable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.overridable_features_ != nullptr) _impl_.overridable_features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::google::protobuf::FeatureSet& FeatureSetDefaults_FeatureSetEditionDefault::_internal_overridable_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.overridable_features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& FeatureSetDefaults_FeatureSetEditionDefault::overridable_features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features)
  return _internal_overridable_features();
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::unsafe_arena_set_allocated_overridable_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.overridable_features_);
  }
  _impl_.overridable_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features)
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::release_overridable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* released = _impl_.overridable_features_;
  _impl_.overridable_features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::unsafe_arena_release_overridable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::FeatureSet* temp = _impl_.overridable_features_;
  _impl_.overridable_features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::_internal_mutable_overridable_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.overridable_features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.overridable_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.overridable_features_;
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::mutable_overridable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000001u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_overridable_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features)
  return _msg;
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::set_allocated_overridable_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.overridable_features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _impl_.overridable_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features)
}

// optional .google.protobuf.FeatureSet fixed_features = 5;
inline bool FeatureSetDefaults_FeatureSetEditionDefault::has_fixed_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.fixed_features_ != nullptr);
  return value;
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::clear_fixed_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.fixed_features_ != nullptr) _impl_.fixed_features_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::FeatureSet& FeatureSetDefaults_FeatureSetEditionDefault::_internal_fixed_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::FeatureSet* p = _impl_.fixed_features_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::FeatureSet&>(::google::protobuf::_FeatureSet_default_instance_);
}
inline const ::google::protobuf::FeatureSet& FeatureSetDefaults_FeatureSetEditionDefault::fixed_features() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features)
  return _internal_fixed_features();
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::unsafe_arena_set_allocated_fixed_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.fixed_features_);
  }
  _impl_.fixed_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features)
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::release_fixed_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::FeatureSet* released = _impl_.fixed_features_;
  _impl_.fixed_features_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::unsafe_arena_release_fixed_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::FeatureSet* temp = _impl_.fixed_features_;
  _impl_.fixed_features_ = nullptr;
  return temp;
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::_internal_mutable_fixed_features() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.fixed_features_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena());
    _impl_.fixed_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p);
  }
  return _impl_.fixed_features_;
}
inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::mutable_fixed_features() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::FeatureSet* _msg = _internal_mutable_fixed_features();
  // @@protoc_insertion_point(field_mutable:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features)
  return _msg;
}
inline void FeatureSetDefaults_FeatureSetEditionDefault::set_allocated_fixed_features(::google::protobuf::FeatureSet* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.fixed_features_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.fixed_features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features)
}

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

// FeatureSetDefaults

// repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1;
inline int FeatureSetDefaults::_internal_defaults_size() const {
  return _internal_defaults().size();
}
inline int FeatureSetDefaults::defaults_size() const {
  return _internal_defaults_size();
}
inline void FeatureSetDefaults::clear_defaults() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.defaults_.Clear();
}
inline ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* FeatureSetDefaults::mutable_defaults(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.FeatureSetDefaults.defaults)
  return _internal_mutable_defaults()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>* FeatureSetDefaults::mutable_defaults()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FeatureSetDefaults.defaults)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_defaults();
}
inline const ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault& FeatureSetDefaults::defaults(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSetDefaults.defaults)
  return _internal_defaults().Get(index);
}
inline ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* FeatureSetDefaults::add_defaults() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* _add = _internal_mutable_defaults()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.FeatureSetDefaults.defaults)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>& FeatureSetDefaults::defaults() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.FeatureSetDefaults.defaults)
  return _internal_defaults();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>&
FeatureSetDefaults::_internal_defaults() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.defaults_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>*
FeatureSetDefaults::_internal_mutable_defaults() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.defaults_;
}

// optional .google.protobuf.Edition minimum_edition = 4;
inline bool FeatureSetDefaults::has_minimum_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline void FeatureSetDefaults::clear_minimum_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.minimum_edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline ::google::protobuf::Edition FeatureSetDefaults::minimum_edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSetDefaults.minimum_edition)
  return _internal_minimum_edition();
}
inline void FeatureSetDefaults::set_minimum_edition(::google::protobuf::Edition value) {
  _internal_set_minimum_edition(value);
  _impl_._has_bits_[0] |= 0x00000001u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSetDefaults.minimum_edition)
}
inline ::google::protobuf::Edition FeatureSetDefaults::_internal_minimum_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.minimum_edition_);
}
inline void FeatureSetDefaults::_internal_set_minimum_edition(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.minimum_edition_ = value;
}

// optional .google.protobuf.Edition maximum_edition = 5;
inline bool FeatureSetDefaults::has_maximum_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline void FeatureSetDefaults::clear_maximum_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.maximum_edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::google::protobuf::Edition FeatureSetDefaults::maximum_edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.FeatureSetDefaults.maximum_edition)
  return _internal_maximum_edition();
}
inline void FeatureSetDefaults::set_maximum_edition(::google::protobuf::Edition value) {
  _internal_set_maximum_edition(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.FeatureSetDefaults.maximum_edition)
}
inline ::google::protobuf::Edition FeatureSetDefaults::_internal_maximum_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Edition>(_impl_.maximum_edition_);
}
inline void FeatureSetDefaults::_internal_set_maximum_edition(::google::protobuf::Edition value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::Edition_IsValid(value));
  _impl_.maximum_edition_ = value;
}

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

// SourceCodeInfo_Location

// repeated int32 path = 1 [packed = true];
inline int SourceCodeInfo_Location::_internal_path_size() const {
  return _internal_path().size();
}
inline int SourceCodeInfo_Location::path_size() const {
  return _internal_path_size();
}
inline void SourceCodeInfo_Location::clear_path() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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().Get(index);
}
inline void SourceCodeInfo_Location::set_path(int index, ::int32_t value) {
  _internal_mutable_path()->Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
}
inline void SourceCodeInfo_Location::add_path(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _internal_mutable_path()->Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
}
inline const ::google::protobuf::RepeatedField<::int32_t>& SourceCodeInfo_Location::path() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
  return _internal_path();
}
inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::mutable_path()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_path();
}
inline const ::google::protobuf::RepeatedField<::int32_t>&
SourceCodeInfo_Location::_internal_path() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.path_;
}
inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::_internal_mutable_path() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.path_;
}

// repeated int32 span = 2 [packed = true];
inline int SourceCodeInfo_Location::_internal_span_size() const {
  return _internal_span().size();
}
inline int SourceCodeInfo_Location::span_size() const {
  return _internal_span_size();
}
inline void SourceCodeInfo_Location::clear_span() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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().Get(index);
}
inline void SourceCodeInfo_Location::set_span(int index, ::int32_t value) {
  _internal_mutable_span()->Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
}
inline void SourceCodeInfo_Location::add_span(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _internal_mutable_span()->Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
}
inline const ::google::protobuf::RepeatedField<::int32_t>& SourceCodeInfo_Location::span() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
  return _internal_span();
}
inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::mutable_span()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_span();
}
inline const ::google::protobuf::RepeatedField<::int32_t>&
SourceCodeInfo_Location::_internal_span() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.span_;
}
inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::_internal_mutable_span() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.leading_comments_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& SourceCodeInfo_Location::leading_comments() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.leading_comments_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
}
inline std::string* SourceCodeInfo_Location::mutable_leading_comments() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.leading_comments_.Get();
}
inline void SourceCodeInfo_Location::_internal_set_leading_comments(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.leading_comments_.Set(value, GetArena());
}
inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.leading_comments_.Mutable( GetArena());
}
inline std::string* SourceCodeInfo_Location::release_leading_comments() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.leading_comments_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.leading_comments_.IsDefault()) {
          _impl_.leading_comments_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.trailing_comments_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& SourceCodeInfo_Location::trailing_comments() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.trailing_comments_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
}
inline std::string* SourceCodeInfo_Location::mutable_trailing_comments() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.trailing_comments_.Get();
}
inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.trailing_comments_.Set(value, GetArena());
}
inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.trailing_comments_.Mutable( GetArena());
}
inline std::string* SourceCodeInfo_Location::release_trailing_comments() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.trailing_comments_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.trailing_comments_.IsDefault()) {
          _impl_.trailing_comments_.Set("", GetArena());
        }
  #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 _internal_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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.leading_detached_comments_.Clear();
}
inline std::string* SourceCodeInfo_Location::add_leading_detached_comments() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  std::string* _s = _internal_mutable_leading_detached_comments()->Add();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return _s;
}
inline const std::string& SourceCodeInfo_Location::leading_detached_comments(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return _internal_leading_detached_comments().Get(index);
}
inline std::string* SourceCodeInfo_Location::mutable_leading_detached_comments(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return _internal_mutable_leading_detached_comments()->Mutable(index);
}
template <typename Arg_, typename... Args_>
inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, Arg_&& value, Args_... args) {
  ::google::protobuf::internal::AssignToString(
      *_internal_mutable_leading_detached_comments()->Mutable(index),
      std::forward<Arg_>(value), args... );
  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
template <typename Arg_, typename... Args_>
inline void SourceCodeInfo_Location::add_leading_detached_comments(Arg_&& value, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::internal::AddToRepeatedPtrField(*_internal_mutable_leading_detached_comments(),
                               std::forward<Arg_>(value),
                               args... );
  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
SourceCodeInfo_Location::leading_detached_comments() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  return _internal_leading_detached_comments();
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
SourceCodeInfo_Location::mutable_leading_detached_comments() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_leading_detached_comments();
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
SourceCodeInfo_Location::_internal_leading_detached_comments() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.leading_detached_comments_;
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
SourceCodeInfo_Location::_internal_mutable_leading_detached_comments() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.leading_detached_comments_;
}

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

// SourceCodeInfo

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

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

// GeneratedCodeInfo_Annotation

// repeated int32 path = 1 [packed = true];
inline int GeneratedCodeInfo_Annotation::_internal_path_size() const {
  return _internal_path().size();
}
inline int GeneratedCodeInfo_Annotation::path_size() const {
  return _internal_path_size();
}
inline void GeneratedCodeInfo_Annotation::clear_path() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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().Get(index);
}
inline void GeneratedCodeInfo_Annotation::set_path(int index, ::int32_t value) {
  _internal_mutable_path()->Set(index, value);
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path)
}
inline void GeneratedCodeInfo_Annotation::add_path(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _internal_mutable_path()->Add(value);
  // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.Annotation.path)
}
inline const ::google::protobuf::RepeatedField<::int32_t>& GeneratedCodeInfo_Annotation::path() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
  return _internal_path();
}
inline ::google::protobuf::RepeatedField<::int32_t>* GeneratedCodeInfo_Annotation::mutable_path()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_path();
}
inline const ::google::protobuf::RepeatedField<::int32_t>&
GeneratedCodeInfo_Annotation::_internal_path() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.path_;
}
inline ::google::protobuf::RepeatedField<::int32_t>* GeneratedCodeInfo_Annotation::_internal_mutable_path() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.source_file_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& GeneratedCodeInfo_Annotation::source_file() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.source_file_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
}
inline std::string* GeneratedCodeInfo_Annotation::mutable_source_file() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.source_file_.Get();
}
inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.source_file_.Set(value, GetArena());
}
inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.source_file_.Mutable( GetArena());
}
inline std::string* GeneratedCodeInfo_Annotation::release_source_file() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.source_file_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.source_file_.IsDefault()) {
          _impl_.source_file_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin)
}
inline ::int32_t GeneratedCodeInfo_Annotation::_internal_begin() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.begin_;
}
inline void GeneratedCodeInfo_Annotation::_internal_set_begin(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end)
}
inline ::int32_t GeneratedCodeInfo_Annotation::_internal_end() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.end_;
}
inline void GeneratedCodeInfo_Annotation::_internal_set_end(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.semantic_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::google::protobuf::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(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic value) {
  _internal_set_semantic(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.semantic)
}
inline ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::_internal_semantic() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::GeneratedCodeInfo_Annotation_Semantic>(_impl_.semantic_);
}
inline void GeneratedCodeInfo_Annotation::_internal_set_semantic(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  assert(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic_IsValid(value));
  _impl_.semantic_ = value;
}

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

// GeneratedCodeInfo

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

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif  // __GNUC__

// @@protoc_insertion_point(namespace_scope)
}  // namespace protobuf
}  // namespace google


namespace google {
namespace protobuf {

template <>
struct is_proto_enum<::google::protobuf::ExtensionRangeOptions_VerificationState> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::ExtensionRangeOptions_VerificationState>() {
  return ::google::protobuf::ExtensionRangeOptions_VerificationState_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FieldDescriptorProto_Type> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FieldDescriptorProto_Type>() {
  return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FieldDescriptorProto_Label> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FieldDescriptorProto_Label>() {
  return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FileOptions_OptimizeMode> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FileOptions_OptimizeMode>() {
  return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FieldOptions_CType> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FieldOptions_CType>() {
  return ::google::protobuf::FieldOptions_CType_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FieldOptions_JSType> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FieldOptions_JSType>() {
  return ::google::protobuf::FieldOptions_JSType_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FieldOptions_OptionRetention> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FieldOptions_OptionRetention>() {
  return ::google::protobuf::FieldOptions_OptionRetention_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FieldOptions_OptionTargetType> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FieldOptions_OptionTargetType>() {
  return ::google::protobuf::FieldOptions_OptionTargetType_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::MethodOptions_IdempotencyLevel> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::MethodOptions_IdempotencyLevel>() {
  return ::google::protobuf::MethodOptions_IdempotencyLevel_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FeatureSet_FieldPresence> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FeatureSet_FieldPresence>() {
  return ::google::protobuf::FeatureSet_FieldPresence_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FeatureSet_EnumType> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FeatureSet_EnumType>() {
  return ::google::protobuf::FeatureSet_EnumType_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FeatureSet_RepeatedFieldEncoding> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FeatureSet_RepeatedFieldEncoding>() {
  return ::google::protobuf::FeatureSet_RepeatedFieldEncoding_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FeatureSet_Utf8Validation> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FeatureSet_Utf8Validation>() {
  return ::google::protobuf::FeatureSet_Utf8Validation_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FeatureSet_MessageEncoding> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FeatureSet_MessageEncoding>() {
  return ::google::protobuf::FeatureSet_MessageEncoding_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::FeatureSet_JsonFormat> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::FeatureSet_JsonFormat>() {
  return ::google::protobuf::FeatureSet_JsonFormat_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::GeneratedCodeInfo_Annotation_Semantic> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::GeneratedCodeInfo_Annotation_Semantic>() {
  return ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic_descriptor();
}
template <>
struct is_proto_enum<::google::protobuf::Edition> : std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor<::google::protobuf::Edition>() {
  return ::google::protobuf::Edition_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh
