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

#include <google/protobuf/descriptor.pb.h>

#include <algorithm>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>

PROTOBUF_PRAGMA_INIT_SEG

namespace _pb = ::PROTOBUF_NAMESPACE_ID;
namespace _pbi = _pb::internal;

PROTOBUF_NAMESPACE_OPEN
PROTOBUF_CONSTEXPR FileDescriptorSet::FileDescriptorSet(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_.file_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct FileDescriptorSetDefaultTypeInternal {
  PROTOBUF_CONSTEXPR FileDescriptorSetDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~FileDescriptorSetDefaultTypeInternal() {}
  union {
    FileDescriptorSet _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_;
PROTOBUF_CONSTEXPR FileDescriptorProto::FileDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.dependency_)*/{}
  , /*decltype(_impl_.message_type_)*/{}
  , /*decltype(_impl_.enum_type_)*/{}
  , /*decltype(_impl_.service_)*/{}
  , /*decltype(_impl_.extension_)*/{}
  , /*decltype(_impl_.public_dependency_)*/{}
  , /*decltype(_impl_.weak_dependency_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.syntax_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr
  , /*decltype(_impl_.source_code_info_)*/nullptr} {}
struct FileDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR FileDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~FileDescriptorProtoDefaultTypeInternal() {}
  union {
    FileDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.options_)*/nullptr
  , /*decltype(_impl_.start_)*/0
  , /*decltype(_impl_.end_)*/0} {}
struct DescriptorProto_ExtensionRangeDefaultTypeInternal {
  PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRangeDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~DescriptorProto_ExtensionRangeDefaultTypeInternal() {}
  union {
    DescriptorProto_ExtensionRange _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_;
PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.start_)*/0
  , /*decltype(_impl_.end_)*/0} {}
struct DescriptorProto_ReservedRangeDefaultTypeInternal {
  PROTOBUF_CONSTEXPR DescriptorProto_ReservedRangeDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~DescriptorProto_ReservedRangeDefaultTypeInternal() {}
  union {
    DescriptorProto_ReservedRange _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_;
PROTOBUF_CONSTEXPR DescriptorProto::DescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.field_)*/{}
  , /*decltype(_impl_.nested_type_)*/{}
  , /*decltype(_impl_.enum_type_)*/{}
  , /*decltype(_impl_.extension_range_)*/{}
  , /*decltype(_impl_.extension_)*/{}
  , /*decltype(_impl_.oneof_decl_)*/{}
  , /*decltype(_impl_.reserved_range_)*/{}
  , /*decltype(_impl_.reserved_name_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr} {}
struct DescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR DescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~DescriptorProtoDefaultTypeInternal() {}
  union {
    DescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR ExtensionRangeOptions::ExtensionRangeOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct ExtensionRangeOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR ExtensionRangeOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~ExtensionRangeOptionsDefaultTypeInternal() {}
  union {
    ExtensionRangeOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_;
PROTOBUF_CONSTEXPR FieldDescriptorProto::FieldDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.extendee_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.type_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.default_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.json_name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr
  , /*decltype(_impl_.number_)*/0
  , /*decltype(_impl_.oneof_index_)*/0
  , /*decltype(_impl_.proto3_optional_)*/false
  , /*decltype(_impl_.label_)*/1
  , /*decltype(_impl_.type_)*/1} {}
struct FieldDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR FieldDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~FieldDescriptorProtoDefaultTypeInternal() {}
  union {
    FieldDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR OneofDescriptorProto::OneofDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr} {}
struct OneofDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR OneofDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~OneofDescriptorProtoDefaultTypeInternal() {}
  union {
    OneofDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.start_)*/0
  , /*decltype(_impl_.end_)*/0} {}
struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal {
  PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() {}
  union {
    EnumDescriptorProto_EnumReservedRange _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal _EnumDescriptorProto_EnumReservedRange_default_instance_;
PROTOBUF_CONSTEXPR EnumDescriptorProto::EnumDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.value_)*/{}
  , /*decltype(_impl_.reserved_range_)*/{}
  , /*decltype(_impl_.reserved_name_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr} {}
struct EnumDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR EnumDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~EnumDescriptorProtoDefaultTypeInternal() {}
  union {
    EnumDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR EnumValueDescriptorProto::EnumValueDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr
  , /*decltype(_impl_.number_)*/0} {}
struct EnumValueDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR EnumValueDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~EnumValueDescriptorProtoDefaultTypeInternal() {}
  union {
    EnumValueDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR ServiceDescriptorProto::ServiceDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.method_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr} {}
struct ServiceDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR ServiceDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~ServiceDescriptorProtoDefaultTypeInternal() {}
  union {
    ServiceDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR MethodDescriptorProto::MethodDescriptorProto(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.name_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.input_type_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.output_type_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.options_)*/nullptr
  , /*decltype(_impl_.client_streaming_)*/false
  , /*decltype(_impl_.server_streaming_)*/false} {}
struct MethodDescriptorProtoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR MethodDescriptorProtoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~MethodDescriptorProtoDefaultTypeInternal() {}
  union {
    MethodDescriptorProto _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_;
PROTOBUF_CONSTEXPR FileOptions::FileOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.java_package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.java_outer_classname_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.go_package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.objc_class_prefix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.csharp_namespace_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.swift_prefix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.php_class_prefix_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.php_namespace_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.php_metadata_namespace_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.ruby_package_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.java_multiple_files_)*/false
  , /*decltype(_impl_.java_generate_equals_and_hash_)*/false
  , /*decltype(_impl_.java_string_check_utf8_)*/false
  , /*decltype(_impl_.cc_generic_services_)*/false
  , /*decltype(_impl_.java_generic_services_)*/false
  , /*decltype(_impl_.py_generic_services_)*/false
  , /*decltype(_impl_.php_generic_services_)*/false
  , /*decltype(_impl_.deprecated_)*/false
  , /*decltype(_impl_.optimize_for_)*/1
  , /*decltype(_impl_.cc_enable_arenas_)*/true} {}
struct FileOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR FileOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~FileOptionsDefaultTypeInternal() {}
  union {
    FileOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileOptionsDefaultTypeInternal _FileOptions_default_instance_;
PROTOBUF_CONSTEXPR MessageOptions::MessageOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.message_set_wire_format_)*/false
  , /*decltype(_impl_.no_standard_descriptor_accessor_)*/false
  , /*decltype(_impl_.deprecated_)*/false
  , /*decltype(_impl_.map_entry_)*/false} {}
struct MessageOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR MessageOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~MessageOptionsDefaultTypeInternal() {}
  union {
    MessageOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_;
PROTOBUF_CONSTEXPR FieldOptions::FieldOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.ctype_)*/0
  , /*decltype(_impl_.jstype_)*/0
  , /*decltype(_impl_.packed_)*/false
  , /*decltype(_impl_.lazy_)*/false
  , /*decltype(_impl_.unverified_lazy_)*/false
  , /*decltype(_impl_.deprecated_)*/false
  , /*decltype(_impl_.weak_)*/false} {}
struct FieldOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR FieldOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~FieldOptionsDefaultTypeInternal() {}
  union {
    FieldOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_;
PROTOBUF_CONSTEXPR OneofOptions::OneofOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct OneofOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR OneofOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~OneofOptionsDefaultTypeInternal() {}
  union {
    OneofOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_;
PROTOBUF_CONSTEXPR EnumOptions::EnumOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.allow_alias_)*/false
  , /*decltype(_impl_.deprecated_)*/false} {}
struct EnumOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR EnumOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~EnumOptionsDefaultTypeInternal() {}
  union {
    EnumOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_;
PROTOBUF_CONSTEXPR EnumValueOptions::EnumValueOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.deprecated_)*/false} {}
struct EnumValueOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR EnumValueOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~EnumValueOptionsDefaultTypeInternal() {}
  union {
    EnumValueOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_;
PROTOBUF_CONSTEXPR ServiceOptions::ServiceOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.deprecated_)*/false} {}
struct ServiceOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR ServiceOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~ServiceOptionsDefaultTypeInternal() {}
  union {
    ServiceOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_;
PROTOBUF_CONSTEXPR MethodOptions::MethodOptions(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._extensions_)*/{}
  , /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.uninterpreted_option_)*/{}
  , /*decltype(_impl_.deprecated_)*/false
  , /*decltype(_impl_.idempotency_level_)*/0} {}
struct MethodOptionsDefaultTypeInternal {
  PROTOBUF_CONSTEXPR MethodOptionsDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~MethodOptionsDefaultTypeInternal() {}
  union {
    MethodOptions _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_;
PROTOBUF_CONSTEXPR UninterpretedOption_NamePart::UninterpretedOption_NamePart(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.name_part_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.is_extension_)*/false} {}
struct UninterpretedOption_NamePartDefaultTypeInternal {
  PROTOBUF_CONSTEXPR UninterpretedOption_NamePartDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~UninterpretedOption_NamePartDefaultTypeInternal() {}
  union {
    UninterpretedOption_NamePart _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_;
PROTOBUF_CONSTEXPR UninterpretedOption::UninterpretedOption(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.name_)*/{}
  , /*decltype(_impl_.identifier_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.string_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.aggregate_value_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.positive_int_value_)*/uint64_t{0u}
  , /*decltype(_impl_.negative_int_value_)*/int64_t{0}
  , /*decltype(_impl_.double_value_)*/0} {}
struct UninterpretedOptionDefaultTypeInternal {
  PROTOBUF_CONSTEXPR UninterpretedOptionDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~UninterpretedOptionDefaultTypeInternal() {}
  union {
    UninterpretedOption _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_;
PROTOBUF_CONSTEXPR SourceCodeInfo_Location::SourceCodeInfo_Location(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.path_)*/{}
  , /*decltype(_impl_._path_cached_byte_size_)*/{0}
  , /*decltype(_impl_.span_)*/{}
  , /*decltype(_impl_._span_cached_byte_size_)*/{0}
  , /*decltype(_impl_.leading_detached_comments_)*/{}
  , /*decltype(_impl_.leading_comments_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.trailing_comments_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}} {}
struct SourceCodeInfo_LocationDefaultTypeInternal {
  PROTOBUF_CONSTEXPR SourceCodeInfo_LocationDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~SourceCodeInfo_LocationDefaultTypeInternal() {}
  union {
    SourceCodeInfo_Location _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_;
PROTOBUF_CONSTEXPR SourceCodeInfo::SourceCodeInfo(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_.location_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct SourceCodeInfoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR SourceCodeInfoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~SourceCodeInfoDefaultTypeInternal() {}
  union {
    SourceCodeInfo _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_;
PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_._has_bits_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}
  , /*decltype(_impl_.path_)*/{}
  , /*decltype(_impl_._path_cached_byte_size_)*/{0}
  , /*decltype(_impl_.source_file_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
  , /*decltype(_impl_.begin_)*/0
  , /*decltype(_impl_.end_)*/0} {}
struct GeneratedCodeInfo_AnnotationDefaultTypeInternal {
  PROTOBUF_CONSTEXPR GeneratedCodeInfo_AnnotationDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~GeneratedCodeInfo_AnnotationDefaultTypeInternal() {}
  union {
    GeneratedCodeInfo_Annotation _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_;
PROTOBUF_CONSTEXPR GeneratedCodeInfo::GeneratedCodeInfo(
    ::_pbi::ConstantInitialized): _impl_{
    /*decltype(_impl_.annotation_)*/{}
  , /*decltype(_impl_._cached_size_)*/{}} {}
struct GeneratedCodeInfoDefaultTypeInternal {
  PROTOBUF_CONSTEXPR GeneratedCodeInfoDefaultTypeInternal()
      : _instance(::_pbi::ConstantInitialized{}) {}
  ~GeneratedCodeInfoDefaultTypeInternal() {}
  union {
    GeneratedCodeInfo _instance;
  };
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_;
PROTOBUF_NAMESPACE_CLOSE
static ::_pb::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;

const uint32_t TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet, _impl_.file_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.package_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.dependency_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.public_dependency_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.weak_dependency_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.message_type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.enum_type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.service_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.extension_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.options_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.source_code_info_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _impl_.syntax_),
  0,
  1,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  3,
  4,
  2,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_.start_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_.end_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange, _impl_.options_),
  1,
  2,
  0,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _impl_.start_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange, _impl_.end_),
  0,
  1,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.field_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.extension_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.nested_type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.enum_type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.extension_range_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.oneof_decl_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.options_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.reserved_range_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::DescriptorProto, _impl_.reserved_name_),
  0,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  ~0u,
  1,
  ~0u,
  ~0u,
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _impl_.uninterpreted_option_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.number_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.label_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.type_name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.extendee_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.default_value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.oneof_index_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.json_name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.options_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _impl_.proto3_optional_),
  0,
  6,
  9,
  10,
  2,
  1,
  3,
  7,
  4,
  5,
  8,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _impl_.options_),
  0,
  1,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _impl_.start_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange, _impl_.end_),
  0,
  1,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.options_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.reserved_range_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto, _impl_.reserved_name_),
  0,
  ~0u,
  1,
  ~0u,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_.number_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto, _impl_.options_),
  0,
  2,
  1,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_.method_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto, _impl_.options_),
  0,
  ~0u,
  1,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.input_type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.output_type_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.options_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.client_streaming_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto, _impl_.server_streaming_),
  0,
  1,
  2,
  3,
  4,
  5,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_package_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_outer_classname_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_multiple_files_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_generate_equals_and_hash_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_string_check_utf8_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.optimize_for_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.go_package_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.cc_generic_services_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.java_generic_services_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.py_generic_services_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_generic_services_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.cc_enable_arenas_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.objc_class_prefix_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.csharp_namespace_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.swift_prefix_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_class_prefix_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_namespace_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.php_metadata_namespace_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.ruby_package_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FileOptions, _impl_.uninterpreted_option_),
  0,
  1,
  10,
  11,
  12,
  18,
  2,
  13,
  14,
  15,
  16,
  17,
  19,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.message_set_wire_format_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.no_standard_descriptor_accessor_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.map_entry_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MessageOptions, _impl_.uninterpreted_option_),
  0,
  1,
  2,
  3,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.ctype_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.packed_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.jstype_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.lazy_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.unverified_lazy_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.weak_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::FieldOptions, _impl_.uninterpreted_option_),
  0,
  2,
  1,
  3,
  4,
  5,
  6,
  ~0u,
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::OneofOptions, _impl_.uninterpreted_option_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_.allow_alias_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumOptions, _impl_.uninterpreted_option_),
  0,
  1,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::EnumValueOptions, _impl_.uninterpreted_option_),
  0,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::ServiceOptions, _impl_.uninterpreted_option_),
  0,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _internal_metadata_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_._extensions_),
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_.deprecated_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_.idempotency_level_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::MethodOptions, _impl_.uninterpreted_option_),
  0,
  1,
  ~0u,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _impl_.name_part_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart, _impl_.is_extension_),
  0,
  1,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.name_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.identifier_value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.positive_int_value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.negative_int_value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.double_value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.string_value_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::UninterpretedOption, _impl_.aggregate_value_),
  ~0u,
  0,
  3,
  4,
  5,
  1,
  2,
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.path_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.span_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.leading_comments_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.trailing_comments_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location, _impl_.leading_detached_comments_),
  ~0u,
  ~0u,
  0,
  1,
  ~0u,
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo, _impl_.location_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_._has_bits_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.path_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.source_file_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.begin_),
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _impl_.end_),
  ~0u,
  0,
  1,
  2,
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  ~0u,  // no _inlined_string_donated_
  ~0u,  // no _split_
  ~0u,  // no sizeof(Split)
  PROTOBUF_FIELD_OFFSET(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _impl_.annotation_),
};
static const ::_pbi::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
  { 0, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileDescriptorSet)},
  { 9, 29, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileDescriptorProto)},
  { 41, 52, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)},
  { 55, 65, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)},
  { 67, 85, -1, sizeof(::PROTOBUF_NAMESPACE_ID::DescriptorProto)},
  { 95, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)},
  { 104, 123, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)},
  { 134, 144, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto)},
  { 146, 156, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange)},
  { 158, 171, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto)},
  { 176, 187, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto)},
  { 190, 201, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto)},
  { 204, 218, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto)},
  { 224, 253, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FileOptions)},
  { 274, 287, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MessageOptions)},
  { 292, 308, -1, sizeof(::PROTOBUF_NAMESPACE_ID::FieldOptions)},
  { 316, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::OneofOptions)},
  { 325, 336, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumOptions)},
  { 339, 349, -1, sizeof(::PROTOBUF_NAMESPACE_ID::EnumValueOptions)},
  { 351, 361, -1, sizeof(::PROTOBUF_NAMESPACE_ID::ServiceOptions)},
  { 363, 374, -1, sizeof(::PROTOBUF_NAMESPACE_ID::MethodOptions)},
  { 377, 387, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)},
  { 389, 404, -1, sizeof(::PROTOBUF_NAMESPACE_ID::UninterpretedOption)},
  { 411, 424, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)},
  { 429, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::SourceCodeInfo)},
  { 438, 450, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)},
  { 454, -1, -1, sizeof(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)},
};

static const ::_pb::Message* const file_default_instances[] = {
  &::PROTOBUF_NAMESPACE_ID::_FileDescriptorSet_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_DescriptorProto_ReservedRange_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_EnumReservedRange_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_NamePart_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_UninterpretedOption_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_Location_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_Annotation_default_instance_._instance,
  &::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_._instance,
};

const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
  "\n google/protobuf/descriptor.proto\022\017goog"
  "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
  "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
  "roto\"\333\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
  "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
  "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
  "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
  "le.protobuf.DescriptorProto\0227\n\tenum_type"
  "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
  "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
  "ServiceDescriptorProto\0228\n\textension\030\007 \003("
  "\0132%.google.protobuf.FieldDescriptorProto"
  "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
  "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
  "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001"
  "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005"
  "field\030\002 \003(\0132%.google.protobuf.FieldDescr"
  "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p"
  "rotobuf.FieldDescriptorProto\0225\n\013nested_t"
  "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr"
  "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf"
  ".EnumDescriptorProto\022H\n\017extension_range\030"
  "\005 \003(\0132/.google.protobuf.DescriptorProto."
  "ExtensionRange\0229\n\noneof_decl\030\010 \003(\0132%.goo"
  "gle.protobuf.OneofDescriptorProto\0220\n\007opt"
  "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti"
  "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro"
  "tobuf.DescriptorProto.ReservedRange\022\025\n\rr"
  "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005"
  "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001("
  "\0132&.google.protobuf.ExtensionRangeOption"
  "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end"
  "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint"
  "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
  ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\325\005\n\024Fiel"
  "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number"
  "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf."
  "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016"
  "2*.google.protobuf.FieldDescriptorProto."
  "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001("
  "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030"
  "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001("
  "\0132\035.google.protobuf.FieldOptions\022\027\n\017prot"
  "o3_optional\030\021 \001(\010\"\266\002\n\004Type\022\017\n\013TYPE_DOUBL"
  "E\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013T"
  "YPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIX"
  "ED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022"
  "\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE"
  "_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT3"
  "2\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n"
  "\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYP"
  "E_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022"
  "\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\""
  "T\n\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\022.\n"
  "\007options\030\002 \001(\0132\035.google.protobuf.OneofOp"
  "tions\"\244\002\n\023EnumDescriptorProto\022\014\n\004name\030\001 "
  "\001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.Enu"
  "mValueDescriptorProto\022-\n\007options\030\003 \001(\0132\034"
  ".google.protobuf.EnumOptions\022N\n\016reserved"
  "_range\030\004 \003(\01326.google.protobuf.EnumDescr"
  "iptorProto.EnumReservedRange\022\025\n\rreserved"
  "_name\030\005 \003(\t\032/\n\021EnumReservedRange\022\r\n\005star"
  "t\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030EnumValueDescrip"
  "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222"
  "\n\007options\030\003 \001(\0132!.google.protobuf.EnumVa"
  "lueOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n"
  "\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.pro"
  "tobuf.MethodDescriptorProto\0220\n\007options\030\003"
  " \001(\0132\037.google.protobuf.ServiceOptions\"\301\001"
  "\n\025MethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n"
  "\ninput_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/"
  "\n\007options\030\004 \001(\0132\036.google.protobuf.Method"
  "Options\022\037\n\020client_streaming\030\005 \001(\010:\005false"
  "\022\037\n\020server_streaming\030\006 \001(\010:\005false\"\245\006\n\013Fi"
  "leOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java_"
  "outer_classname\030\010 \001(\t\022\"\n\023java_multiple_f"
  "iles\030\n \001(\010:\005false\022)\n\035java_generate_equal"
  "s_and_hash\030\024 \001(\010B\002\030\001\022%\n\026java_string_chec"
  "k_utf8\030\033 \001(\010:\005false\022F\n\014optimize_for\030\t \001("
  "\0162).google.protobuf.FileOptions.Optimize"
  "Mode:\005SPEED\022\022\n\ngo_package\030\013 \001(\t\022\"\n\023cc_ge"
  "neric_services\030\020 \001(\010:\005false\022$\n\025java_gene"
  "ric_services\030\021 \001(\010:\005false\022\"\n\023py_generic_"
  "services\030\022 \001(\010:\005false\022#\n\024php_generic_ser"
  "vices\030* \001(\010:\005false\022\031\n\ndeprecated\030\027 \001(\010:\005"
  "false\022\036\n\020cc_enable_arenas\030\037 \001(\010:\004true\022\031\n"
  "\021objc_class_prefix\030$ \001(\t\022\030\n\020csharp_names"
  "pace\030% \001(\t\022\024\n\014swift_prefix\030\' \001(\t\022\030\n\020php_"
  "class_prefix\030( \001(\t\022\025\n\rphp_namespace\030) \001("
  "\t\022\036\n\026php_metadata_namespace\030, \001(\t\022\024\n\014rub"
  "y_package\030- \001(\t\022C\n\024uninterpreted_option\030"
  "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
  "tion\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_"
  "SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020"
  "\'\"\204\002\n\016MessageOptions\022&\n\027message_set_wire"
  "_format\030\001 \001(\010:\005false\022.\n\037no_standard_desc"
  "riptor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprecat"
  "ed\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024un"
  "interpreted_option\030\347\007 \003(\0132$.google.proto"
  "buf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005"
  "J\004\010\005\020\006J\004\010\006\020\007J\004\010\010\020\tJ\004\010\t\020\n\"\276\003\n\014FieldOption"
  "s\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Field"
  "Options.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n"
  "\006jstype\030\006 \001(\0162$.google.protobuf.FieldOpt"
  "ions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fa"
  "lse\022\036\n\017unverified_lazy\030\017 \001(\010:\005false\022\031\n\nd"
  "eprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005fa"
  "lse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
  "gle.protobuf.UninterpretedOption\"/\n\005CTyp"
  "e\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020"
  "\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING\020"
  "\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\"^\n\014One"
  "ofOptions\022C\n\024uninterpreted_option\030\347\007 \003(\013"
  "2$.google.protobuf.UninterpretedOption*\t"
  "\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow_alias"
  "\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uni"
  "nterpreted_option\030\347\007 \003(\0132$.google.protob"
  "uf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\""
  "}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001(\010:"
  "\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
  "google.protobuf.UninterpretedOption*\t\010\350\007"
  "\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030!"
  " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
  "(\0132$.google.protobuf.UninterpretedOption"
  "*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\ndepreca"
  "ted\030! \001(\010:\005false\022_\n\021idempotency_level\030\" "
  "\001(\0162/.google.protobuf.MethodOptions.Idem"
  "potencyLevel:\023IDEMPOTENCY_UNKNOWN\022C\n\024uni"
  "nterpreted_option\030\347\007 \003(\0132$.google.protob"
  "uf.UninterpretedOption\"P\n\020IdempotencyLev"
  "el\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_SIDE_E"
  "FFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023"
  "UninterpretedOption\022;\n\004name\030\002 \003(\0132-.goog"
  "le.protobuf.UninterpretedOption.NamePart"
  "\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022positive_i"
  "nt_value\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001"
  "(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_value"
  "\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NameP"
  "art\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002"
  " \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003("
  "\0132(.google.protobuf.SourceCodeInfo.Locat"
  "ion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004sp"
  "an\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031"
  "\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_det"
  "ached_comments\030\006 \003(\t\"\247\001\n\021GeneratedCodeIn"
  "fo\022A\n\nannotation\030\001 \003(\0132-.google.protobuf"
  ".GeneratedCodeInfo.Annotation\032O\n\nAnnotat"
  "ion\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001"
  "(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B~\n\023com.go"
  "ogle.protobufB\020DescriptorProtosH\001Z-googl"
  "e.golang.org/protobuf/types/descriptorpb"
  "\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Reflection"
  ;
static ::_pbi::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once;
const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
    false, false, 6078, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto,
    "google/protobuf/descriptor.proto",
    &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, nullptr, 0, 27,
    schemas, file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets,
    file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto,
    file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto,
};
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter() {
  return &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto;
}

// Force running AddDescriptors() at dynamic initialization time.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
PROTOBUF_NAMESPACE_OPEN
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[0];
}
bool FieldDescriptorProto_Type_IsValid(int value) {
  switch (value) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
      return true;
    default:
      return false;
  }
}

#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
constexpr FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
constexpr int FieldDescriptorProto::Type_ARRAYSIZE;
#endif  // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[1];
}
bool FieldDescriptorProto_Label_IsValid(int value) {
  switch (value) {
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
constexpr FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
constexpr FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
constexpr int FieldDescriptorProto::Label_ARRAYSIZE;
#endif  // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[2];
}
bool FileOptions_OptimizeMode_IsValid(int value) {
  switch (value) {
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr FileOptions_OptimizeMode FileOptions::SPEED;
constexpr FileOptions_OptimizeMode FileOptions::CODE_SIZE;
constexpr FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
constexpr FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
constexpr int FileOptions::OptimizeMode_ARRAYSIZE;
#endif  // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_CType_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[3];
}
bool FieldOptions_CType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr FieldOptions_CType FieldOptions::STRING;
constexpr FieldOptions_CType FieldOptions::CORD;
constexpr FieldOptions_CType FieldOptions::STRING_PIECE;
constexpr FieldOptions_CType FieldOptions::CType_MIN;
constexpr FieldOptions_CType FieldOptions::CType_MAX;
constexpr int FieldOptions::CType_ARRAYSIZE;
#endif  // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldOptions_JSType_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[4];
}
bool FieldOptions_JSType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr FieldOptions_JSType FieldOptions::JS_NORMAL;
constexpr FieldOptions_JSType FieldOptions::JS_STRING;
constexpr FieldOptions_JSType FieldOptions::JS_NUMBER;
constexpr FieldOptions_JSType FieldOptions::JSType_MIN;
constexpr FieldOptions_JSType FieldOptions::JSType_MAX;
constexpr int FieldOptions::JSType_ARRAYSIZE;
#endif  // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor() {
  ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[5];
}
bool MethodOptions_IdempotencyLevel_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENCY_UNKNOWN;
constexpr MethodOptions_IdempotencyLevel MethodOptions::NO_SIDE_EFFECTS;
constexpr MethodOptions_IdempotencyLevel MethodOptions::IDEMPOTENT;
constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MIN;
constexpr MethodOptions_IdempotencyLevel MethodOptions::IdempotencyLevel_MAX;
constexpr int MethodOptions::IdempotencyLevel_ARRAYSIZE;
#endif  // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))

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

class FileDescriptorSet::_Internal {
 public:
};

FileDescriptorSet::FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet)
}
FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  FileDescriptorSet* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_.file_){from._impl_.file_}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
}

inline void FileDescriptorSet::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_.file_){arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

FileDescriptorSet::~FileDescriptorSet() {
  // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void FileDescriptorSet::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.file_.~RepeatedPtrField();
}

void FileDescriptorSet::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void FileDescriptorSet::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.file_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* FileDescriptorSet::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.FileDescriptorProto file = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_file(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* FileDescriptorSet::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.FileDescriptorProto file = 1;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_file_size()); i < n; i++) {
    const auto& repfield = this->_internal_file(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet)
  return target;
}

size_t FileDescriptorSet::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorSet)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.FileDescriptorProto file = 1;
  total_size += 1UL * this->_internal_file_size();
  for (const auto& msg : this->_impl_.file_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorSet::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    FileDescriptorSet::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorSet::GetClassData() const { return &_class_data_; }


void FileDescriptorSet::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<FileDescriptorSet*>(&to_msg);
  auto& from = static_cast<const FileDescriptorSet&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.file_.MergeFrom(from._impl_.file_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorSet)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FileDescriptorSet::IsInitialized() const {
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.file_))
    return false;
  return true;
}

void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.file_.InternalSwap(&other->_impl_.file_);
}

::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorSet::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]);
}

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

class FileDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<FileDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_package(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::FileOptions& options(const FileDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo& source_code_info(const FileDescriptorProto* msg);
  static void set_has_source_code_info(HasBits* has_bits) {
    (*has_bits)[0] |= 16u;
  }
  static void set_has_syntax(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::FileOptions&
FileDescriptorProto::_Internal::options(const FileDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
const ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo&
FileDescriptorProto::_Internal::source_code_info(const FileDescriptorProto* msg) {
  return *msg->_impl_.source_code_info_;
}
FileDescriptorProto::FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto)
}
FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  FileDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.dependency_){from._impl_.dependency_}
    , decltype(_impl_.message_type_){from._impl_.message_type_}
    , decltype(_impl_.enum_type_){from._impl_.enum_type_}
    , decltype(_impl_.service_){from._impl_.service_}
    , decltype(_impl_.extension_){from._impl_.extension_}
    , decltype(_impl_.public_dependency_){from._impl_.public_dependency_}
    , decltype(_impl_.weak_dependency_){from._impl_.weak_dependency_}
    , decltype(_impl_.name_){}
    , decltype(_impl_.package_){}
    , decltype(_impl_.syntax_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.source_code_info_){nullptr}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  _impl_.package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_package()) {
    _this->_impl_.package_.Set(from._internal_package(), 
      _this->GetArenaForAllocation());
  }
  _impl_.syntax_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.syntax_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_syntax()) {
    _this->_impl_.syntax_.Set(from._internal_syntax(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::FileOptions(*from._impl_.options_);
  }
  if (from._internal_has_source_code_info()) {
    _this->_impl_.source_code_info_ = new ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo(*from._impl_.source_code_info_);
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
}

inline void FileDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.dependency_){arena}
    , decltype(_impl_.message_type_){arena}
    , decltype(_impl_.enum_type_){arena}
    , decltype(_impl_.service_){arena}
    , decltype(_impl_.extension_){arena}
    , decltype(_impl_.public_dependency_){arena}
    , decltype(_impl_.weak_dependency_){arena}
    , decltype(_impl_.name_){}
    , decltype(_impl_.package_){}
    , decltype(_impl_.syntax_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.source_code_info_){nullptr}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.syntax_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.syntax_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

FileDescriptorProto::~FileDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void FileDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.dependency_.~RepeatedPtrField();
  _impl_.message_type_.~RepeatedPtrField();
  _impl_.enum_type_.~RepeatedPtrField();
  _impl_.service_.~RepeatedPtrField();
  _impl_.extension_.~RepeatedPtrField();
  _impl_.public_dependency_.~RepeatedField();
  _impl_.weak_dependency_.~RepeatedField();
  _impl_.name_.Destroy();
  _impl_.package_.Destroy();
  _impl_.syntax_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
  if (this != internal_default_instance()) delete _impl_.source_code_info_;
}

void FileDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void FileDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.dependency_.Clear();
  _impl_.message_type_.Clear();
  _impl_.enum_type_.Clear();
  _impl_.service_.Clear();
  _impl_.extension_.Clear();
  _impl_.public_dependency_.Clear();
  _impl_.weak_dependency_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000001fu) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.package_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      _impl_.syntax_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
    if (cached_has_bits & 0x00000010u) {
      GOOGLE_DCHECK(_impl_.source_code_info_ != nullptr);
      _impl_.source_code_info_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* FileDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string package = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          auto str = _internal_mutable_package();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.package");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // repeated string dependency = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          ptr -= 1;
          do {
            ptr += 1;
            auto str = _internal_add_dependency();
            ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
            CHK_(ptr);
            #ifndef NDEBUG
            ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.dependency");
            #endif  // !NDEBUG
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.DescriptorProto message_type = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_message_type(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_enum_type(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_service(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
      case 7:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_extension(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<58>(ptr));
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.FileOptions options = 8;
      case 8:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
      case 9:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
          ptr = ctx->ParseMessage(_internal_mutable_source_code_info(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated int32 public_dependency = 10;
      case 10:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) {
          ptr -= 1;
          do {
            ptr += 1;
            _internal_add_public_dependency(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<80>(ptr));
        } else if (static_cast<uint8_t>(tag) == 82) {
          ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_public_dependency(), ptr, ctx);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated int32 weak_dependency = 11;
      case 11:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 88)) {
          ptr -= 1;
          do {
            ptr += 1;
            _internal_add_weak_dependency(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<88>(ptr));
        } else if (static_cast<uint8_t>(tag) == 90) {
          ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_weak_dependency(), ptr, ctx);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string syntax = 12;
      case 12:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 98)) {
          auto str = _internal_mutable_syntax();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileDescriptorProto.syntax");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* FileDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // optional string package = 2;
  if (cached_has_bits & 0x00000002u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_package().data(), static_cast<int>(this->_internal_package().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.package");
    target = stream->WriteStringMaybeAliased(
        2, this->_internal_package(), target);
  }

  // repeated string dependency = 3;
  for (int i = 0, n = this->_internal_dependency_size(); i < n; i++) {
    const auto& s = this->_internal_dependency(i);
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      s.data(), static_cast<int>(s.length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.dependency");
    target = stream->WriteString(3, s, target);
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_message_type_size()); i < n; i++) {
    const auto& repfield = this->_internal_message_type(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_enum_type_size()); i < n; i++) {
    const auto& repfield = this->_internal_enum_type(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(5, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_service_size()); i < n; i++) {
    const auto& repfield = this->_internal_service(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_extension_size()); i < n; i++) {
    const auto& repfield = this->_internal_extension(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(7, repfield, repfield.GetCachedSize(), target, stream);
  }

  // optional .google.protobuf.FileOptions options = 8;
  if (cached_has_bits & 0x00000008u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(8, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  if (cached_has_bits & 0x00000010u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(9, _Internal::source_code_info(this),
        _Internal::source_code_info(this).GetCachedSize(), target, stream);
  }

  // repeated int32 public_dependency = 10;
  for (int i = 0, n = this->_internal_public_dependency_size(); i < n; i++) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(10, this->_internal_public_dependency(i), target);
  }

  // repeated int32 weak_dependency = 11;
  for (int i = 0, n = this->_internal_weak_dependency_size(); i < n; i++) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(11, this->_internal_weak_dependency(i), target);
  }

  // optional string syntax = 12;
  if (cached_has_bits & 0x00000004u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_syntax().data(), static_cast<int>(this->_internal_syntax().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileDescriptorProto.syntax");
    target = stream->WriteStringMaybeAliased(
        12, this->_internal_syntax(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto)
  return target;
}

size_t FileDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated string dependency = 3;
  total_size += 1 *
      ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.dependency_.size());
  for (int i = 0, n = _impl_.dependency_.size(); i < n; i++) {
    total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
      _impl_.dependency_.Get(i));
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  total_size += 1UL * this->_internal_message_type_size();
  for (const auto& msg : this->_impl_.message_type_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  total_size += 1UL * this->_internal_enum_type_size();
  for (const auto& msg : this->_impl_.enum_type_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  total_size += 1UL * this->_internal_service_size();
  for (const auto& msg : this->_impl_.service_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  total_size += 1UL * this->_internal_extension_size();
  for (const auto& msg : this->_impl_.extension_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated int32 public_dependency = 10;
  {
    size_t data_size = ::_pbi::WireFormatLite::
      Int32Size(this->_impl_.public_dependency_);
    total_size += 1 *
                  ::_pbi::FromIntSize(this->_internal_public_dependency_size());
    total_size += data_size;
  }

  // repeated int32 weak_dependency = 11;
  {
    size_t data_size = ::_pbi::WireFormatLite::
      Int32Size(this->_impl_.weak_dependency_);
    total_size += 1 *
                  ::_pbi::FromIntSize(this->_internal_weak_dependency_size());
    total_size += data_size;
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000001fu) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional string package = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_package());
    }

    // optional string syntax = 12;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_syntax());
    }

    // optional .google.protobuf.FileOptions options = 8;
    if (cached_has_bits & 0x00000008u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

    // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    if (cached_has_bits & 0x00000010u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.source_code_info_);
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    FileDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileDescriptorProto::GetClassData() const { return &_class_data_; }


void FileDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<FileDescriptorProto*>(&to_msg);
  auto& from = static_cast<const FileDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.dependency_.MergeFrom(from._impl_.dependency_);
  _this->_impl_.message_type_.MergeFrom(from._impl_.message_type_);
  _this->_impl_.enum_type_.MergeFrom(from._impl_.enum_type_);
  _this->_impl_.service_.MergeFrom(from._impl_.service_);
  _this->_impl_.extension_.MergeFrom(from._impl_.extension_);
  _this->_impl_.public_dependency_.MergeFrom(from._impl_.public_dependency_);
  _this->_impl_.weak_dependency_.MergeFrom(from._impl_.weak_dependency_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000001fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_package(from._internal_package());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_internal_set_syntax(from._internal_syntax());
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FileOptions::MergeFrom(
          from._internal_options());
    }
    if (cached_has_bits & 0x00000010u) {
      _this->_internal_mutable_source_code_info()->::PROTOBUF_NAMESPACE_ID::SourceCodeInfo::MergeFrom(
          from._internal_source_code_info());
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FileDescriptorProto::IsInitialized() const {
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.message_type_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.enum_type_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.service_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.extension_))
    return false;
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.dependency_.InternalSwap(&other->_impl_.dependency_);
  _impl_.message_type_.InternalSwap(&other->_impl_.message_type_);
  _impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_);
  _impl_.service_.InternalSwap(&other->_impl_.service_);
  _impl_.extension_.InternalSwap(&other->_impl_.extension_);
  _impl_.public_dependency_.InternalSwap(&other->_impl_.public_dependency_);
  _impl_.weak_dependency_.InternalSwap(&other->_impl_.weak_dependency_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.package_, lhs_arena,
      &other->_impl_.package_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.syntax_, lhs_arena,
      &other->_impl_.syntax_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.source_code_info_)
      + sizeof(FileDescriptorProto::_impl_.source_code_info_)
      - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.options_)>(
          reinterpret_cast<char*>(&_impl_.options_),
          reinterpret_cast<char*>(&other->_impl_.options_));
}

::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]);
}

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

class DescriptorProto_ExtensionRange::_Internal {
 public:
  using HasBits = decltype(std::declval<DescriptorProto_ExtensionRange>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._has_bits_);
  static void set_has_start(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_end(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& options(const DescriptorProto_ExtensionRange* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions&
DescriptorProto_ExtensionRange::_Internal::options(const DescriptorProto_ExtensionRange* msg) {
  return *msg->_impl_.options_;
}
DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange)
}
DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  DescriptorProto_ExtensionRange* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.start_){}
    , decltype(_impl_.end_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(*from._impl_.options_);
  }
  ::memcpy(&_impl_.start_, &from._impl_.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
    reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
}

inline void DescriptorProto_ExtensionRange::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.start_){0}
    , decltype(_impl_.end_){0}
  };
}

DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void DescriptorProto_ExtensionRange::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  if (this != internal_default_instance()) delete _impl_.options_;
}

void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void DescriptorProto_ExtensionRange::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    GOOGLE_DCHECK(_impl_.options_ != nullptr);
    _impl_.options_->Clear();
  }
  if (cached_has_bits & 0x00000006u) {
    ::memset(&_impl_.start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.end_) -
        reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional int32 start = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_start(&has_bits);
          _impl_.start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional int32 end = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_end(&has_bits);
          _impl_.end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.ExtensionRangeOptions options = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* DescriptorProto_ExtensionRange::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000004u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
  }

  // optional .google.protobuf.ExtensionRangeOptions options = 3;
  if (cached_has_bits & 0x00000001u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(3, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange)
  return target;
}

size_t DescriptorProto_ExtensionRange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ExtensionRange)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    // optional .google.protobuf.ExtensionRangeOptions options = 3;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

    // optional int32 start = 1;
    if (cached_has_bits & 0x00000002u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_start());
    }

    // optional int32 end = 2;
    if (cached_has_bits & 0x00000004u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ExtensionRange::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    DescriptorProto_ExtensionRange::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ExtensionRange::GetClassData() const { return &_class_data_; }


void DescriptorProto_ExtensionRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<DescriptorProto_ExtensionRange*>(&to_msg);
  auto& from = static_cast<const DescriptorProto_ExtensionRange&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::MergeFrom(
          from._internal_options());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.start_ = from._impl_.start_;
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.end_ = from._impl_.end_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ExtensionRange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool DescriptorProto_ExtensionRange::IsInitialized() const {
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.end_)
      + sizeof(DescriptorProto_ExtensionRange::_impl_.end_)
      - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.options_)>(
          reinterpret_cast<char*>(&_impl_.options_),
          reinterpret_cast<char*>(&other->_impl_.options_));
}

::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]);
}

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

class DescriptorProto_ReservedRange::_Internal {
 public:
  using HasBits = decltype(std::declval<DescriptorProto_ReservedRange>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._has_bits_);
  static void set_has_start(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_end(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange)
}
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  DescriptorProto_ReservedRange* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.start_){}
    , decltype(_impl_.end_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  ::memcpy(&_impl_.start_, &from._impl_.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
    reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange)
}

inline void DescriptorProto_ReservedRange::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.start_){0}
    , decltype(_impl_.end_){0}
  };
}

DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() {
  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void DescriptorProto_ReservedRange::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
}

void DescriptorProto_ReservedRange::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void DescriptorProto_ReservedRange::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    ::memset(&_impl_.start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.end_) -
        reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional int32 start = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_start(&has_bits);
          _impl_.start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional int32 end = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_end(&has_bits);
          _impl_.end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* DescriptorProto_ReservedRange::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange)
  return target;
}

size_t DescriptorProto_ReservedRange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ReservedRange)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional int32 start = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_start());
    }

    // optional int32 end = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto_ReservedRange::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    DescriptorProto_ReservedRange::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto_ReservedRange::GetClassData() const { return &_class_data_; }


void DescriptorProto_ReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<DescriptorProto_ReservedRange*>(&to_msg);
  auto& from = static_cast<const DescriptorProto_ReservedRange&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_impl_.start_ = from._impl_.start_;
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.end_ = from._impl_.end_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void DescriptorProto_ReservedRange::CopyFrom(const DescriptorProto_ReservedRange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ReservedRange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool DescriptorProto_ReservedRange::IsInitialized() const {
  return true;
}

void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_.end_)
      + sizeof(DescriptorProto_ReservedRange::_impl_.end_)
      - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_.start_)>(
          reinterpret_cast<char*>(&_impl_.start_),
          reinterpret_cast<char*>(&other->_impl_.start_));
}

::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ReservedRange::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]);
}

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

class DescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<DescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::MessageOptions& options(const DescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::MessageOptions&
DescriptorProto::_Internal::options(const DescriptorProto* msg) {
  return *msg->_impl_.options_;
}
DescriptorProto::DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto)
}
DescriptorProto::DescriptorProto(const DescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  DescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.field_){from._impl_.field_}
    , decltype(_impl_.nested_type_){from._impl_.nested_type_}
    , decltype(_impl_.enum_type_){from._impl_.enum_type_}
    , decltype(_impl_.extension_range_){from._impl_.extension_range_}
    , decltype(_impl_.extension_){from._impl_.extension_}
    , decltype(_impl_.oneof_decl_){from._impl_.oneof_decl_}
    , decltype(_impl_.reserved_range_){from._impl_.reserved_range_}
    , decltype(_impl_.reserved_name_){from._impl_.reserved_name_}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::MessageOptions(*from._impl_.options_);
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
}

inline void DescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.field_){arena}
    , decltype(_impl_.nested_type_){arena}
    , decltype(_impl_.enum_type_){arena}
    , decltype(_impl_.extension_range_){arena}
    , decltype(_impl_.extension_){arena}
    , decltype(_impl_.oneof_decl_){arena}
    , decltype(_impl_.reserved_range_){arena}
    , decltype(_impl_.reserved_name_){arena}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

DescriptorProto::~DescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void DescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.field_.~RepeatedPtrField();
  _impl_.nested_type_.~RepeatedPtrField();
  _impl_.enum_type_.~RepeatedPtrField();
  _impl_.extension_range_.~RepeatedPtrField();
  _impl_.extension_.~RepeatedPtrField();
  _impl_.oneof_decl_.~RepeatedPtrField();
  _impl_.reserved_range_.~RepeatedPtrField();
  _impl_.reserved_name_.~RepeatedPtrField();
  _impl_.name_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void DescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void DescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.field_.Clear();
  _impl_.nested_type_.Clear();
  _impl_.enum_type_.Clear();
  _impl_.extension_range_.Clear();
  _impl_.extension_.Clear();
  _impl_.oneof_decl_.Clear();
  _impl_.reserved_range_.Clear();
  _impl_.reserved_name_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* DescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.DescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.FieldDescriptorProto field = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_field(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.DescriptorProto nested_type = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_nested_type(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<26>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_enum_type(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_extension_range(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.FieldDescriptorProto extension = 6;
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_extension(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.MessageOptions options = 7;
      case 7:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
      case 8:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_oneof_decl(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<66>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
      case 9:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_reserved_range(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<74>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated string reserved_name = 10;
      case 10:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) {
          ptr -= 1;
          do {
            ptr += 1;
            auto str = _internal_add_reserved_name();
            ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
            CHK_(ptr);
            #ifndef NDEBUG
            ::_pbi::VerifyUTF8(str, "google.protobuf.DescriptorProto.reserved_name");
            #endif  // !NDEBUG
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<82>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* DescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.DescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_field_size()); i < n; i++) {
    const auto& repfield = this->_internal_field(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_nested_type_size()); i < n; i++) {
    const auto& repfield = this->_internal_nested_type(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(3, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_enum_type_size()); i < n; i++) {
    const auto& repfield = this->_internal_enum_type(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_extension_range_size()); i < n; i++) {
    const auto& repfield = this->_internal_extension_range(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(5, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_extension_size()); i < n; i++) {
    const auto& repfield = this->_internal_extension(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(6, repfield, repfield.GetCachedSize(), target, stream);
  }

  // optional .google.protobuf.MessageOptions options = 7;
  if (cached_has_bits & 0x00000002u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(7, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_oneof_decl_size()); i < n; i++) {
    const auto& repfield = this->_internal_oneof_decl(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(8, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_reserved_range_size()); i < n; i++) {
    const auto& repfield = this->_internal_reserved_range(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(9, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated string reserved_name = 10;
  for (int i = 0, n = this->_internal_reserved_name_size(); i < n; i++) {
    const auto& s = this->_internal_reserved_name(i);
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      s.data(), static_cast<int>(s.length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.DescriptorProto.reserved_name");
    target = stream->WriteString(10, s, target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto)
  return target;
}

size_t DescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  total_size += 1UL * this->_internal_field_size();
  for (const auto& msg : this->_impl_.field_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  total_size += 1UL * this->_internal_nested_type_size();
  for (const auto& msg : this->_impl_.nested_type_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  total_size += 1UL * this->_internal_enum_type_size();
  for (const auto& msg : this->_impl_.enum_type_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  total_size += 1UL * this->_internal_extension_range_size();
  for (const auto& msg : this->_impl_.extension_range_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  total_size += 1UL * this->_internal_extension_size();
  for (const auto& msg : this->_impl_.extension_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
  total_size += 1UL * this->_internal_oneof_decl_size();
  for (const auto& msg : this->_impl_.oneof_decl_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
  total_size += 1UL * this->_internal_reserved_range_size();
  for (const auto& msg : this->_impl_.reserved_range_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated string reserved_name = 10;
  total_size += 1 *
      ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.reserved_name_.size());
  for (int i = 0, n = _impl_.reserved_name_.size(); i < n; i++) {
    total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
      _impl_.reserved_name_.Get(i));
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional .google.protobuf.MessageOptions options = 7;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    DescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DescriptorProto::GetClassData() const { return &_class_data_; }


void DescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<DescriptorProto*>(&to_msg);
  auto& from = static_cast<const DescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.field_.MergeFrom(from._impl_.field_);
  _this->_impl_.nested_type_.MergeFrom(from._impl_.nested_type_);
  _this->_impl_.enum_type_.MergeFrom(from._impl_.enum_type_);
  _this->_impl_.extension_range_.MergeFrom(from._impl_.extension_range_);
  _this->_impl_.extension_.MergeFrom(from._impl_.extension_);
  _this->_impl_.oneof_decl_.MergeFrom(from._impl_.oneof_decl_);
  _this->_impl_.reserved_range_.MergeFrom(from._impl_.reserved_range_);
  _this->_impl_.reserved_name_.MergeFrom(from._impl_.reserved_name_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MessageOptions::MergeFrom(
          from._internal_options());
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void DescriptorProto::CopyFrom(const DescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool DescriptorProto::IsInitialized() const {
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.field_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.nested_type_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.enum_type_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.extension_range_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.extension_))
    return false;
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.oneof_decl_))
    return false;
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void DescriptorProto::InternalSwap(DescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.field_.InternalSwap(&other->_impl_.field_);
  _impl_.nested_type_.InternalSwap(&other->_impl_.nested_type_);
  _impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_);
  _impl_.extension_range_.InternalSwap(&other->_impl_.extension_range_);
  _impl_.extension_.InternalSwap(&other->_impl_.extension_);
  _impl_.oneof_decl_.InternalSwap(&other->_impl_.oneof_decl_);
  _impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_);
  _impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  swap(_impl_.options_, other->_impl_.options_);
}

::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]);
}

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

class ExtensionRangeOptions::_Internal {
 public:
};

ExtensionRangeOptions::ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions)
}
ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  ExtensionRangeOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions)
}

inline void ExtensionRangeOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_.uninterpreted_option_){arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

ExtensionRangeOptions::~ExtensionRangeOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void ExtensionRangeOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void ExtensionRangeOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void ExtensionRangeOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* ExtensionRangeOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ExtensionRangeOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ExtensionRangeOptions)
  return target;
}

size_t ExtensionRangeOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ExtensionRangeOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ExtensionRangeOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    ExtensionRangeOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ExtensionRangeOptions::GetClassData() const { return &_class_data_; }


void ExtensionRangeOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<ExtensionRangeOptions*>(&to_msg);
  auto& from = static_cast<const ExtensionRangeOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void ExtensionRangeOptions::CopyFrom(const ExtensionRangeOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ExtensionRangeOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ExtensionRangeOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
}

::PROTOBUF_NAMESPACE_ID::Metadata ExtensionRangeOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]);
}

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

class FieldDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<FieldDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_number(HasBits* has_bits) {
    (*has_bits)[0] |= 64u;
  }
  static void set_has_label(HasBits* has_bits) {
    (*has_bits)[0] |= 512u;
  }
  static void set_has_type(HasBits* has_bits) {
    (*has_bits)[0] |= 1024u;
  }
  static void set_has_type_name(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static void set_has_extendee(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_default_value(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
  static void set_has_oneof_index(HasBits* has_bits) {
    (*has_bits)[0] |= 128u;
  }
  static void set_has_json_name(HasBits* has_bits) {
    (*has_bits)[0] |= 16u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::FieldOptions& options(const FieldDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 32u;
  }
  static void set_has_proto3_optional(HasBits* has_bits) {
    (*has_bits)[0] |= 256u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::FieldOptions&
FieldDescriptorProto::_Internal::options(const FieldDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
FieldDescriptorProto::FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto)
}
FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  FieldDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.extendee_){}
    , decltype(_impl_.type_name_){}
    , decltype(_impl_.default_value_){}
    , decltype(_impl_.json_name_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.number_){}
    , decltype(_impl_.oneof_index_){}
    , decltype(_impl_.proto3_optional_){}
    , decltype(_impl_.label_){}
    , decltype(_impl_.type_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  _impl_.extendee_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.extendee_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_extendee()) {
    _this->_impl_.extendee_.Set(from._internal_extendee(), 
      _this->GetArenaForAllocation());
  }
  _impl_.type_name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.type_name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_type_name()) {
    _this->_impl_.type_name_.Set(from._internal_type_name(), 
      _this->GetArenaForAllocation());
  }
  _impl_.default_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.default_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_default_value()) {
    _this->_impl_.default_value_.Set(from._internal_default_value(), 
      _this->GetArenaForAllocation());
  }
  _impl_.json_name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.json_name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_json_name()) {
    _this->_impl_.json_name_.Set(from._internal_json_name(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::FieldOptions(*from._impl_.options_);
  }
  ::memcpy(&_impl_.number_, &from._impl_.number_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.type_) -
    reinterpret_cast<char*>(&_impl_.number_)) + sizeof(_impl_.type_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
}

inline void FieldDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.extendee_){}
    , decltype(_impl_.type_name_){}
    , decltype(_impl_.default_value_){}
    , decltype(_impl_.json_name_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.number_){0}
    , decltype(_impl_.oneof_index_){0}
    , decltype(_impl_.proto3_optional_){false}
    , decltype(_impl_.label_){1}
    , decltype(_impl_.type_){1}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.extendee_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.extendee_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.type_name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.type_name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.default_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.default_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.json_name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.json_name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

FieldDescriptorProto::~FieldDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void FieldDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.name_.Destroy();
  _impl_.extendee_.Destroy();
  _impl_.type_name_.Destroy();
  _impl_.default_value_.Destroy();
  _impl_.json_name_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void FieldDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void FieldDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000003fu) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.extendee_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      _impl_.type_name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      _impl_.default_value_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000010u) {
      _impl_.json_name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000020u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  if (cached_has_bits & 0x000000c0u) {
    ::memset(&_impl_.number_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.oneof_index_) -
        reinterpret_cast<char*>(&_impl_.number_)) + sizeof(_impl_.oneof_index_));
  }
  if (cached_has_bits & 0x00000700u) {
    _impl_.proto3_optional_ = false;
    _impl_.label_ = 1;
    _impl_.type_ = 1;
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string extendee = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          auto str = _internal_mutable_extendee();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.extendee");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional int32 number = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
          _Internal::set_has_number(&has_bits);
          _impl_.number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
          uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
          if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_IsValid(val))) {
            _internal_set_label(static_cast<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label>(val));
          } else {
            ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(4, val, mutable_unknown_fields());
          }
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
          uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
          if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_IsValid(val))) {
            _internal_set_type(static_cast<::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type>(val));
          } else {
            ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(5, val, mutable_unknown_fields());
          }
        } else
          goto handle_unusual;
        continue;
      // optional string type_name = 6;
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
          auto str = _internal_mutable_type_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.type_name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string default_value = 7;
      case 7:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          auto str = _internal_mutable_default_value();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.default_value");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.FieldOptions options = 8;
      case 8:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional int32 oneof_index = 9;
      case 9:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 72)) {
          _Internal::set_has_oneof_index(&has_bits);
          _impl_.oneof_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string json_name = 10;
      case 10:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 82)) {
          auto str = _internal_mutable_json_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FieldDescriptorProto.json_name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional bool proto3_optional = 17;
      case 17:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 136)) {
          _Internal::set_has_proto3_optional(&has_bits);
          _impl_.proto3_optional_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* FieldDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // optional string extendee = 2;
  if (cached_has_bits & 0x00000002u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_extendee().data(), static_cast<int>(this->_internal_extendee().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.extendee");
    target = stream->WriteStringMaybeAliased(
        2, this->_internal_extendee(), target);
  }

  // optional int32 number = 3;
  if (cached_has_bits & 0x00000040u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target);
  }

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  if (cached_has_bits & 0x00000200u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      4, this->_internal_label(), target);
  }

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  if (cached_has_bits & 0x00000400u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      5, this->_internal_type(), target);
  }

  // optional string type_name = 6;
  if (cached_has_bits & 0x00000004u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_type_name().data(), static_cast<int>(this->_internal_type_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.type_name");
    target = stream->WriteStringMaybeAliased(
        6, this->_internal_type_name(), target);
  }

  // optional string default_value = 7;
  if (cached_has_bits & 0x00000008u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_default_value().data(), static_cast<int>(this->_internal_default_value().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.default_value");
    target = stream->WriteStringMaybeAliased(
        7, this->_internal_default_value(), target);
  }

  // optional .google.protobuf.FieldOptions options = 8;
  if (cached_has_bits & 0x00000020u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(8, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  // optional int32 oneof_index = 9;
  if (cached_has_bits & 0x00000080u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(9, this->_internal_oneof_index(), target);
  }

  // optional string json_name = 10;
  if (cached_has_bits & 0x00000010u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_json_name().data(), static_cast<int>(this->_internal_json_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FieldDescriptorProto.json_name");
    target = stream->WriteStringMaybeAliased(
        10, this->_internal_json_name(), target);
  }

  // optional bool proto3_optional = 17;
  if (cached_has_bits & 0x00000100u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(17, this->_internal_proto3_optional(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto)
  return target;
}

size_t FieldDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x000000ffu) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional string extendee = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_extendee());
    }

    // optional string type_name = 6;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_type_name());
    }

    // optional string default_value = 7;
    if (cached_has_bits & 0x00000008u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_default_value());
    }

    // optional string json_name = 10;
    if (cached_has_bits & 0x00000010u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_json_name());
    }

    // optional .google.protobuf.FieldOptions options = 8;
    if (cached_has_bits & 0x00000020u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

    // optional int32 number = 3;
    if (cached_has_bits & 0x00000040u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_number());
    }

    // optional int32 oneof_index = 9;
    if (cached_has_bits & 0x00000080u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_oneof_index());
    }

  }
  if (cached_has_bits & 0x00000700u) {
    // optional bool proto3_optional = 17;
    if (cached_has_bits & 0x00000100u) {
      total_size += 2 + 1;
    }

    // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    if (cached_has_bits & 0x00000200u) {
      total_size += 1 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_label());
    }

    // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    if (cached_has_bits & 0x00000400u) {
      total_size += 1 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_type());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    FieldDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldDescriptorProto::GetClassData() const { return &_class_data_; }


void FieldDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<FieldDescriptorProto*>(&to_msg);
  auto& from = static_cast<const FieldDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x000000ffu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_extendee(from._internal_extendee());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_internal_set_type_name(from._internal_type_name());
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_internal_set_default_value(from._internal_default_value());
    }
    if (cached_has_bits & 0x00000010u) {
      _this->_internal_set_json_name(from._internal_json_name());
    }
    if (cached_has_bits & 0x00000020u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::FieldOptions::MergeFrom(
          from._internal_options());
    }
    if (cached_has_bits & 0x00000040u) {
      _this->_impl_.number_ = from._impl_.number_;
    }
    if (cached_has_bits & 0x00000080u) {
      _this->_impl_.oneof_index_ = from._impl_.oneof_index_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  if (cached_has_bits & 0x00000700u) {
    if (cached_has_bits & 0x00000100u) {
      _this->_impl_.proto3_optional_ = from._impl_.proto3_optional_;
    }
    if (cached_has_bits & 0x00000200u) {
      _this->_impl_.label_ = from._impl_.label_;
    }
    if (cached_has_bits & 0x00000400u) {
      _this->_impl_.type_ = from._impl_.type_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FieldDescriptorProto::IsInitialized() const {
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.extendee_, lhs_arena,
      &other->_impl_.extendee_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.type_name_, lhs_arena,
      &other->_impl_.type_name_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.default_value_, lhs_arena,
      &other->_impl_.default_value_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.json_name_, lhs_arena,
      &other->_impl_.json_name_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.proto3_optional_)
      + sizeof(FieldDescriptorProto::_impl_.proto3_optional_)
      - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.options_)>(
          reinterpret_cast<char*>(&_impl_.options_),
          reinterpret_cast<char*>(&other->_impl_.options_));
  swap(_impl_.label_, other->_impl_.label_);
  swap(_impl_.type_, other->_impl_.type_);
}

::PROTOBUF_NAMESPACE_ID::Metadata FieldDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]);
}

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

class OneofDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<OneofDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::OneofOptions& options(const OneofDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::OneofOptions&
OneofDescriptorProto::_Internal::options(const OneofDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
OneofDescriptorProto::OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto)
}
OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  OneofDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::OneofOptions(*from._impl_.options_);
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
}

inline void OneofDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

OneofDescriptorProto::~OneofDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void OneofDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.name_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void OneofDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void OneofDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.OneofDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.OneofOptions options = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* OneofDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.OneofDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // optional .google.protobuf.OneofOptions options = 2;
  if (cached_has_bits & 0x00000002u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(2, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto)
  return target;
}

size_t OneofDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional .google.protobuf.OneofOptions options = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    OneofDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofDescriptorProto::GetClassData() const { return &_class_data_; }


void OneofDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<OneofDescriptorProto*>(&to_msg);
  auto& from = static_cast<const OneofDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::OneofOptions::MergeFrom(
          from._internal_options());
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool OneofDescriptorProto::IsInitialized() const {
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  swap(_impl_.options_, other->_impl_.options_);
}

::PROTOBUF_NAMESPACE_ID::Metadata OneofDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]);
}

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

class EnumDescriptorProto_EnumReservedRange::_Internal {
 public:
  using HasBits = decltype(std::declval<EnumDescriptorProto_EnumReservedRange>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_);
  static void set_has_start(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_end(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
}
EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  EnumDescriptorProto_EnumReservedRange* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.start_){}
    , decltype(_impl_.end_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  ::memcpy(&_impl_.start_, &from._impl_.start_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
    reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
}

inline void EnumDescriptorProto_EnumReservedRange::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.start_){0}
    , decltype(_impl_.end_){0}
  };
}

EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void EnumDescriptorProto_EnumReservedRange::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
}

void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void EnumDescriptorProto_EnumReservedRange::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    ::memset(&_impl_.start_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.end_) -
        reinterpret_cast<char*>(&_impl_.start_)) + sizeof(_impl_.end_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional int32 start = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_start(&has_bits);
          _impl_.start_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional int32 end = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_end(&has_bits);
          _impl_.end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* EnumDescriptorProto_EnumReservedRange::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional int32 start = 1;
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(1, this->_internal_start(), target);
  }

  // optional int32 end = 2;
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_end(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  return target;
}

size_t EnumDescriptorProto_EnumReservedRange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional int32 start = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_start());
    }

    // optional int32 end = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto_EnumReservedRange::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    EnumDescriptorProto_EnumReservedRange::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto_EnumReservedRange::GetClassData() const { return &_class_data_; }


void EnumDescriptorProto_EnumReservedRange::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<EnumDescriptorProto_EnumReservedRange*>(&to_msg);
  auto& from = static_cast<const EnumDescriptorProto_EnumReservedRange&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_impl_.start_ = from._impl_.start_;
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.end_ = from._impl_.end_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void EnumDescriptorProto_EnumReservedRange::CopyFrom(const EnumDescriptorProto_EnumReservedRange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumDescriptorProto_EnumReservedRange::IsInitialized() const {
  return true;
}

void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_.end_)
      + sizeof(EnumDescriptorProto_EnumReservedRange::_impl_.end_)
      - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_.start_)>(
          reinterpret_cast<char*>(&_impl_.start_),
          reinterpret_cast<char*>(&other->_impl_.start_));
}

::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]);
}

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

class EnumDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<EnumDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::EnumOptions& options(const EnumDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::EnumOptions&
EnumDescriptorProto::_Internal::options(const EnumDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
EnumDescriptorProto::EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto)
}
EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  EnumDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.value_){from._impl_.value_}
    , decltype(_impl_.reserved_range_){from._impl_.reserved_range_}
    , decltype(_impl_.reserved_name_){from._impl_.reserved_name_}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::EnumOptions(*from._impl_.options_);
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
}

inline void EnumDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.value_){arena}
    , decltype(_impl_.reserved_range_){arena}
    , decltype(_impl_.reserved_name_){arena}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

EnumDescriptorProto::~EnumDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void EnumDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.value_.~RepeatedPtrField();
  _impl_.reserved_range_.~RepeatedPtrField();
  _impl_.reserved_name_.~RepeatedPtrField();
  _impl_.name_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void EnumDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void EnumDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.value_.Clear();
  _impl_.reserved_range_.Clear();
  _impl_.reserved_name_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_value(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.EnumOptions options = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_reserved_range(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<34>(ptr));
        } else
          goto handle_unusual;
        continue;
      // repeated string reserved_name = 5;
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
          ptr -= 1;
          do {
            ptr += 1;
            auto str = _internal_add_reserved_name();
            ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
            CHK_(ptr);
            #ifndef NDEBUG
            ::_pbi::VerifyUTF8(str, "google.protobuf.EnumDescriptorProto.reserved_name");
            #endif  // !NDEBUG
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<42>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* EnumDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_value_size()); i < n; i++) {
    const auto& repfield = this->_internal_value(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
  }

  // optional .google.protobuf.EnumOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(3, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_reserved_range_size()); i < n; i++) {
    const auto& repfield = this->_internal_reserved_range(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(4, repfield, repfield.GetCachedSize(), target, stream);
  }

  // repeated string reserved_name = 5;
  for (int i = 0, n = this->_internal_reserved_name_size(); i < n; i++) {
    const auto& s = this->_internal_reserved_name(i);
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      s.data(), static_cast<int>(s.length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumDescriptorProto.reserved_name");
    target = stream->WriteString(5, s, target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto)
  return target;
}

size_t EnumDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  total_size += 1UL * this->_internal_value_size();
  for (const auto& msg : this->_impl_.value_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
  total_size += 1UL * this->_internal_reserved_range_size();
  for (const auto& msg : this->_impl_.reserved_range_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // repeated string reserved_name = 5;
  total_size += 1 *
      ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.reserved_name_.size());
  for (int i = 0, n = _impl_.reserved_name_.size(); i < n; i++) {
    total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
      _impl_.reserved_name_.Get(i));
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional .google.protobuf.EnumOptions options = 3;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    EnumDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumDescriptorProto::GetClassData() const { return &_class_data_; }


void EnumDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<EnumDescriptorProto*>(&to_msg);
  auto& from = static_cast<const EnumDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.value_.MergeFrom(from._impl_.value_);
  _this->_impl_.reserved_range_.MergeFrom(from._impl_.reserved_range_);
  _this->_impl_.reserved_name_.MergeFrom(from._impl_.reserved_name_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumOptions::MergeFrom(
          from._internal_options());
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumDescriptorProto::IsInitialized() const {
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.value_))
    return false;
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.value_.InternalSwap(&other->_impl_.value_);
  _impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_);
  _impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  swap(_impl_.options_, other->_impl_.options_);
}

::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]);
}

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

class EnumValueDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<EnumValueDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_number(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions& options(const EnumValueDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::EnumValueOptions&
EnumValueDescriptorProto::_Internal::options(const EnumValueDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
EnumValueDescriptorProto::EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto)
}
EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  EnumValueDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.number_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::EnumValueOptions(*from._impl_.options_);
  }
  _this->_impl_.number_ = from._impl_.number_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
}

inline void EnumValueDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.number_){0}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

EnumValueDescriptorProto::~EnumValueDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void EnumValueDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.name_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void EnumValueDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void EnumValueDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  _impl_.number_ = 0;
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.EnumValueDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional int32 number = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_number(&has_bits);
          _impl_.number_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.EnumValueOptions options = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* EnumValueDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.EnumValueDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // optional int32 number = 2;
  if (cached_has_bits & 0x00000004u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target);
  }

  // optional .google.protobuf.EnumValueOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(3, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto)
  return target;
}

size_t EnumValueDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional .google.protobuf.EnumValueOptions options = 3;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

    // optional int32 number = 2;
    if (cached_has_bits & 0x00000004u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_number());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    EnumValueDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueDescriptorProto::GetClassData() const { return &_class_data_; }


void EnumValueDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<EnumValueDescriptorProto*>(&to_msg);
  auto& from = static_cast<const EnumValueDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::EnumValueOptions::MergeFrom(
          from._internal_options());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.number_ = from._impl_.number_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumValueDescriptorProto::IsInitialized() const {
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.number_)
      + sizeof(EnumValueDescriptorProto::_impl_.number_)
      - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.options_)>(
          reinterpret_cast<char*>(&_impl_.options_),
          reinterpret_cast<char*>(&other->_impl_.options_));
}

::PROTOBUF_NAMESPACE_ID::Metadata EnumValueDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]);
}

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

class ServiceDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<ServiceDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::ServiceOptions& options(const ServiceDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::ServiceOptions&
ServiceDescriptorProto::_Internal::options(const ServiceDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
ServiceDescriptorProto::ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto)
}
ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  ServiceDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.method_){from._impl_.method_}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::ServiceOptions(*from._impl_.options_);
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
}

inline void ServiceDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.method_){arena}
    , decltype(_impl_.name_){}
    , decltype(_impl_.options_){nullptr}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

ServiceDescriptorProto::~ServiceDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void ServiceDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.method_.~RepeatedPtrField();
  _impl_.name_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void ServiceDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void ServiceDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.method_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.ServiceDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.MethodDescriptorProto method = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_method(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.ServiceOptions options = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* ServiceDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.ServiceDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_method_size()); i < n; i++) {
    const auto& repfield = this->_internal_method(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
  }

  // optional .google.protobuf.ServiceOptions options = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(3, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto)
  return target;
}

size_t ServiceDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  total_size += 1UL * this->_internal_method_size();
  for (const auto& msg : this->_impl_.method_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional .google.protobuf.ServiceOptions options = 3;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    ServiceDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceDescriptorProto::GetClassData() const { return &_class_data_; }


void ServiceDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<ServiceDescriptorProto*>(&to_msg);
  auto& from = static_cast<const ServiceDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.method_.MergeFrom(from._impl_.method_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::ServiceOptions::MergeFrom(
          from._internal_options());
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ServiceDescriptorProto::IsInitialized() const {
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.method_))
    return false;
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.method_.InternalSwap(&other->_impl_.method_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  swap(_impl_.options_, other->_impl_.options_);
}

::PROTOBUF_NAMESPACE_ID::Metadata ServiceDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]);
}

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

class MethodDescriptorProto::_Internal {
 public:
  using HasBits = decltype(std::declval<MethodDescriptorProto>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._has_bits_);
  static void set_has_name(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_input_type(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_output_type(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static const ::PROTOBUF_NAMESPACE_ID::MethodOptions& options(const MethodDescriptorProto* msg);
  static void set_has_options(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
  static void set_has_client_streaming(HasBits* has_bits) {
    (*has_bits)[0] |= 16u;
  }
  static void set_has_server_streaming(HasBits* has_bits) {
    (*has_bits)[0] |= 32u;
  }
};

const ::PROTOBUF_NAMESPACE_ID::MethodOptions&
MethodDescriptorProto::_Internal::options(const MethodDescriptorProto* msg) {
  return *msg->_impl_.options_;
}
MethodDescriptorProto::MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto)
}
MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  MethodDescriptorProto* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.input_type_){}
    , decltype(_impl_.output_type_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.client_streaming_){}
    , decltype(_impl_.server_streaming_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name()) {
    _this->_impl_.name_.Set(from._internal_name(), 
      _this->GetArenaForAllocation());
  }
  _impl_.input_type_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.input_type_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_input_type()) {
    _this->_impl_.input_type_.Set(from._internal_input_type(), 
      _this->GetArenaForAllocation());
  }
  _impl_.output_type_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.output_type_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_output_type()) {
    _this->_impl_.output_type_.Set(from._internal_output_type(), 
      _this->GetArenaForAllocation());
  }
  if (from._internal_has_options()) {
    _this->_impl_.options_ = new ::PROTOBUF_NAMESPACE_ID::MethodOptions(*from._impl_.options_);
  }
  ::memcpy(&_impl_.client_streaming_, &from._impl_.client_streaming_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.server_streaming_) -
    reinterpret_cast<char*>(&_impl_.client_streaming_)) + sizeof(_impl_.server_streaming_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
}

inline void MethodDescriptorProto::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){}
    , decltype(_impl_.input_type_){}
    , decltype(_impl_.output_type_){}
    , decltype(_impl_.options_){nullptr}
    , decltype(_impl_.client_streaming_){false}
    , decltype(_impl_.server_streaming_){false}
  };
  _impl_.name_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.input_type_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.input_type_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.output_type_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.output_type_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

MethodDescriptorProto::~MethodDescriptorProto() {
  // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void MethodDescriptorProto::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.name_.Destroy();
  _impl_.input_type_.Destroy();
  _impl_.output_type_.Destroy();
  if (this != internal_default_instance()) delete _impl_.options_;
}

void MethodDescriptorProto::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void MethodDescriptorProto::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.input_type_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      _impl_.output_type_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      GOOGLE_DCHECK(_impl_.options_ != nullptr);
      _impl_.options_->Clear();
    }
  }
  ::memset(&_impl_.client_streaming_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&_impl_.server_streaming_) -
      reinterpret_cast<char*>(&_impl_.client_streaming_)) + sizeof(_impl_.server_streaming_));
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string name = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.name");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string input_type = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          auto str = _internal_mutable_input_type();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.input_type");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string output_type = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          auto str = _internal_mutable_output_type();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.MethodDescriptorProto.output_type");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.MethodOptions options = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
          ptr = ctx->ParseMessage(_internal_mutable_options(), ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool client_streaming = 5 [default = false];
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
          _Internal::set_has_client_streaming(&has_bits);
          _impl_.client_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool server_streaming = 6 [default = false];
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) {
          _Internal::set_has_server_streaming(&has_bits);
          _impl_.server_streaming_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* MethodDescriptorProto::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name().data(), static_cast<int>(this->_internal_name().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.name");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name(), target);
  }

  // optional string input_type = 2;
  if (cached_has_bits & 0x00000002u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_input_type().data(), static_cast<int>(this->_internal_input_type().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.input_type");
    target = stream->WriteStringMaybeAliased(
        2, this->_internal_input_type(), target);
  }

  // optional string output_type = 3;
  if (cached_has_bits & 0x00000004u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_output_type().data(), static_cast<int>(this->_internal_output_type().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.MethodDescriptorProto.output_type");
    target = stream->WriteStringMaybeAliased(
        3, this->_internal_output_type(), target);
  }

  // optional .google.protobuf.MethodOptions options = 4;
  if (cached_has_bits & 0x00000008u) {
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
      InternalWriteMessage(4, _Internal::options(this),
        _Internal::options(this).GetCachedSize(), target, stream);
  }

  // optional bool client_streaming = 5 [default = false];
  if (cached_has_bits & 0x00000010u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(5, this->_internal_client_streaming(), target);
  }

  // optional bool server_streaming = 6 [default = false];
  if (cached_has_bits & 0x00000020u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(6, this->_internal_server_streaming(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto)
  return target;
}

size_t MethodDescriptorProto::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodDescriptorProto)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000003fu) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_name());
    }

    // optional string input_type = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_input_type());
    }

    // optional string output_type = 3;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_output_type());
    }

    // optional .google.protobuf.MethodOptions options = 4;
    if (cached_has_bits & 0x00000008u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
          *_impl_.options_);
    }

    // optional bool client_streaming = 5 [default = false];
    if (cached_has_bits & 0x00000010u) {
      total_size += 1 + 1;
    }

    // optional bool server_streaming = 6 [default = false];
    if (cached_has_bits & 0x00000020u) {
      total_size += 1 + 1;
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodDescriptorProto::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    MethodDescriptorProto::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodDescriptorProto::GetClassData() const { return &_class_data_; }


void MethodDescriptorProto::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<MethodDescriptorProto*>(&to_msg);
  auto& from = static_cast<const MethodDescriptorProto&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000003fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_input_type(from._internal_input_type());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_internal_set_output_type(from._internal_output_type());
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_internal_mutable_options()->::PROTOBUF_NAMESPACE_ID::MethodOptions::MergeFrom(
          from._internal_options());
    }
    if (cached_has_bits & 0x00000010u) {
      _this->_impl_.client_streaming_ = from._impl_.client_streaming_;
    }
    if (cached_has_bits & 0x00000020u) {
      _this->_impl_.server_streaming_ = from._impl_.server_streaming_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodDescriptorProto)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MethodDescriptorProto::IsInitialized() const {
  if (_internal_has_options()) {
    if (!_impl_.options_->IsInitialized()) return false;
  }
  return true;
}

void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_, lhs_arena,
      &other->_impl_.name_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.input_type_, lhs_arena,
      &other->_impl_.input_type_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.output_type_, lhs_arena,
      &other->_impl_.output_type_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.server_streaming_)
      + sizeof(MethodDescriptorProto::_impl_.server_streaming_)
      - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.options_)>(
          reinterpret_cast<char*>(&_impl_.options_),
          reinterpret_cast<char*>(&other->_impl_.options_));
}

::PROTOBUF_NAMESPACE_ID::Metadata MethodDescriptorProto::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]);
}

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

class FileOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<FileOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._has_bits_);
  static void set_has_java_package(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_java_outer_classname(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_java_multiple_files(HasBits* has_bits) {
    (*has_bits)[0] |= 1024u;
  }
  static void set_has_java_generate_equals_and_hash(HasBits* has_bits) {
    (*has_bits)[0] |= 2048u;
  }
  static void set_has_java_string_check_utf8(HasBits* has_bits) {
    (*has_bits)[0] |= 4096u;
  }
  static void set_has_optimize_for(HasBits* has_bits) {
    (*has_bits)[0] |= 262144u;
  }
  static void set_has_go_package(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static void set_has_cc_generic_services(HasBits* has_bits) {
    (*has_bits)[0] |= 8192u;
  }
  static void set_has_java_generic_services(HasBits* has_bits) {
    (*has_bits)[0] |= 16384u;
  }
  static void set_has_py_generic_services(HasBits* has_bits) {
    (*has_bits)[0] |= 32768u;
  }
  static void set_has_php_generic_services(HasBits* has_bits) {
    (*has_bits)[0] |= 65536u;
  }
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 131072u;
  }
  static void set_has_cc_enable_arenas(HasBits* has_bits) {
    (*has_bits)[0] |= 524288u;
  }
  static void set_has_objc_class_prefix(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
  static void set_has_csharp_namespace(HasBits* has_bits) {
    (*has_bits)[0] |= 16u;
  }
  static void set_has_swift_prefix(HasBits* has_bits) {
    (*has_bits)[0] |= 32u;
  }
  static void set_has_php_class_prefix(HasBits* has_bits) {
    (*has_bits)[0] |= 64u;
  }
  static void set_has_php_namespace(HasBits* has_bits) {
    (*has_bits)[0] |= 128u;
  }
  static void set_has_php_metadata_namespace(HasBits* has_bits) {
    (*has_bits)[0] |= 256u;
  }
  static void set_has_ruby_package(HasBits* has_bits) {
    (*has_bits)[0] |= 512u;
  }
};

FileOptions::FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions)
}
FileOptions::FileOptions(const FileOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  FileOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.java_package_){}
    , decltype(_impl_.java_outer_classname_){}
    , decltype(_impl_.go_package_){}
    , decltype(_impl_.objc_class_prefix_){}
    , decltype(_impl_.csharp_namespace_){}
    , decltype(_impl_.swift_prefix_){}
    , decltype(_impl_.php_class_prefix_){}
    , decltype(_impl_.php_namespace_){}
    , decltype(_impl_.php_metadata_namespace_){}
    , decltype(_impl_.ruby_package_){}
    , decltype(_impl_.java_multiple_files_){}
    , decltype(_impl_.java_generate_equals_and_hash_){}
    , decltype(_impl_.java_string_check_utf8_){}
    , decltype(_impl_.cc_generic_services_){}
    , decltype(_impl_.java_generic_services_){}
    , decltype(_impl_.py_generic_services_){}
    , decltype(_impl_.php_generic_services_){}
    , decltype(_impl_.deprecated_){}
    , decltype(_impl_.optimize_for_){}
    , decltype(_impl_.cc_enable_arenas_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _impl_.java_package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.java_package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_java_package()) {
    _this->_impl_.java_package_.Set(from._internal_java_package(), 
      _this->GetArenaForAllocation());
  }
  _impl_.java_outer_classname_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_java_outer_classname()) {
    _this->_impl_.java_outer_classname_.Set(from._internal_java_outer_classname(), 
      _this->GetArenaForAllocation());
  }
  _impl_.go_package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.go_package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_go_package()) {
    _this->_impl_.go_package_.Set(from._internal_go_package(), 
      _this->GetArenaForAllocation());
  }
  _impl_.objc_class_prefix_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_objc_class_prefix()) {
    _this->_impl_.objc_class_prefix_.Set(from._internal_objc_class_prefix(), 
      _this->GetArenaForAllocation());
  }
  _impl_.csharp_namespace_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_csharp_namespace()) {
    _this->_impl_.csharp_namespace_.Set(from._internal_csharp_namespace(), 
      _this->GetArenaForAllocation());
  }
  _impl_.swift_prefix_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.swift_prefix_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_swift_prefix()) {
    _this->_impl_.swift_prefix_.Set(from._internal_swift_prefix(), 
      _this->GetArenaForAllocation());
  }
  _impl_.php_class_prefix_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_php_class_prefix()) {
    _this->_impl_.php_class_prefix_.Set(from._internal_php_class_prefix(), 
      _this->GetArenaForAllocation());
  }
  _impl_.php_namespace_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.php_namespace_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_php_namespace()) {
    _this->_impl_.php_namespace_.Set(from._internal_php_namespace(), 
      _this->GetArenaForAllocation());
  }
  _impl_.php_metadata_namespace_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_php_metadata_namespace()) {
    _this->_impl_.php_metadata_namespace_.Set(from._internal_php_metadata_namespace(), 
      _this->GetArenaForAllocation());
  }
  _impl_.ruby_package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.ruby_package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_ruby_package()) {
    _this->_impl_.ruby_package_.Set(from._internal_ruby_package(), 
      _this->GetArenaForAllocation());
  }
  ::memcpy(&_impl_.java_multiple_files_, &from._impl_.java_multiple_files_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.cc_enable_arenas_) -
    reinterpret_cast<char*>(&_impl_.java_multiple_files_)) + sizeof(_impl_.cc_enable_arenas_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
}

inline void FileOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.java_package_){}
    , decltype(_impl_.java_outer_classname_){}
    , decltype(_impl_.go_package_){}
    , decltype(_impl_.objc_class_prefix_){}
    , decltype(_impl_.csharp_namespace_){}
    , decltype(_impl_.swift_prefix_){}
    , decltype(_impl_.php_class_prefix_){}
    , decltype(_impl_.php_namespace_){}
    , decltype(_impl_.php_metadata_namespace_){}
    , decltype(_impl_.ruby_package_){}
    , decltype(_impl_.java_multiple_files_){false}
    , decltype(_impl_.java_generate_equals_and_hash_){false}
    , decltype(_impl_.java_string_check_utf8_){false}
    , decltype(_impl_.cc_generic_services_){false}
    , decltype(_impl_.java_generic_services_){false}
    , decltype(_impl_.py_generic_services_){false}
    , decltype(_impl_.php_generic_services_){false}
    , decltype(_impl_.deprecated_){false}
    , decltype(_impl_.optimize_for_){1}
    , decltype(_impl_.cc_enable_arenas_){true}
  };
  _impl_.java_package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.java_package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.java_outer_classname_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.java_outer_classname_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.go_package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.go_package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.objc_class_prefix_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.objc_class_prefix_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.csharp_namespace_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.csharp_namespace_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.swift_prefix_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.swift_prefix_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.php_class_prefix_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.php_class_prefix_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.php_namespace_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.php_namespace_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.php_metadata_namespace_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.php_metadata_namespace_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.ruby_package_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.ruby_package_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

FileOptions::~FileOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.FileOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void FileOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
  _impl_.java_package_.Destroy();
  _impl_.java_outer_classname_.Destroy();
  _impl_.go_package_.Destroy();
  _impl_.objc_class_prefix_.Destroy();
  _impl_.csharp_namespace_.Destroy();
  _impl_.swift_prefix_.Destroy();
  _impl_.php_class_prefix_.Destroy();
  _impl_.php_namespace_.Destroy();
  _impl_.php_metadata_namespace_.Destroy();
  _impl_.ruby_package_.Destroy();
}

void FileOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void FileOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x000000ffu) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.java_package_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.java_outer_classname_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      _impl_.go_package_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      _impl_.objc_class_prefix_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000010u) {
      _impl_.csharp_namespace_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000020u) {
      _impl_.swift_prefix_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000040u) {
      _impl_.php_class_prefix_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000080u) {
      _impl_.php_namespace_.ClearNonDefaultToEmpty();
    }
  }
  if (cached_has_bits & 0x00000300u) {
    if (cached_has_bits & 0x00000100u) {
      _impl_.php_metadata_namespace_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000200u) {
      _impl_.ruby_package_.ClearNonDefaultToEmpty();
    }
  }
  if (cached_has_bits & 0x0000fc00u) {
    ::memset(&_impl_.java_multiple_files_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.py_generic_services_) -
        reinterpret_cast<char*>(&_impl_.java_multiple_files_)) + sizeof(_impl_.py_generic_services_));
  }
  if (cached_has_bits & 0x000f0000u) {
    ::memset(&_impl_.php_generic_services_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.deprecated_) -
        reinterpret_cast<char*>(&_impl_.php_generic_services_)) + sizeof(_impl_.deprecated_));
    _impl_.optimize_for_ = 1;
    _impl_.cc_enable_arenas_ = true;
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* FileOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional string java_package = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_java_package();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.java_package");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string java_outer_classname = 8;
      case 8:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
          auto str = _internal_mutable_java_outer_classname();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.java_outer_classname");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
      case 9:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 72)) {
          uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
          if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_IsValid(val))) {
            _internal_set_optimize_for(static_cast<::PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode>(val));
          } else {
            ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(9, val, mutable_unknown_fields());
          }
        } else
          goto handle_unusual;
        continue;
      // optional bool java_multiple_files = 10 [default = false];
      case 10:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) {
          _Internal::set_has_java_multiple_files(&has_bits);
          _impl_.java_multiple_files_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string go_package = 11;
      case 11:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 90)) {
          auto str = _internal_mutable_go_package();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.go_package");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional bool cc_generic_services = 16 [default = false];
      case 16:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 128)) {
          _Internal::set_has_cc_generic_services(&has_bits);
          _impl_.cc_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool java_generic_services = 17 [default = false];
      case 17:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 136)) {
          _Internal::set_has_java_generic_services(&has_bits);
          _impl_.java_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool py_generic_services = 18 [default = false];
      case 18:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 144)) {
          _Internal::set_has_py_generic_services(&has_bits);
          _impl_.py_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
      case 20:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 160)) {
          _Internal::set_has_java_generate_equals_and_hash(&has_bits);
          _impl_.java_generate_equals_and_hash_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool deprecated = 23 [default = false];
      case 23:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 184)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool java_string_check_utf8 = 27 [default = false];
      case 27:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 216)) {
          _Internal::set_has_java_string_check_utf8(&has_bits);
          _impl_.java_string_check_utf8_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool cc_enable_arenas = 31 [default = true];
      case 31:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 248)) {
          _Internal::set_has_cc_enable_arenas(&has_bits);
          _impl_.cc_enable_arenas_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string objc_class_prefix = 36;
      case 36:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
          auto str = _internal_mutable_objc_class_prefix();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.objc_class_prefix");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string csharp_namespace = 37;
      case 37:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
          auto str = _internal_mutable_csharp_namespace();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.csharp_namespace");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string swift_prefix = 39;
      case 39:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          auto str = _internal_mutable_swift_prefix();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.swift_prefix");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string php_class_prefix = 40;
      case 40:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
          auto str = _internal_mutable_php_class_prefix();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.php_class_prefix");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string php_namespace = 41;
      case 41:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 74)) {
          auto str = _internal_mutable_php_namespace();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.php_namespace");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional bool php_generic_services = 42 [default = false];
      case 42:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) {
          _Internal::set_has_php_generic_services(&has_bits);
          _impl_.php_generic_services_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string php_metadata_namespace = 44;
      case 44:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 98)) {
          auto str = _internal_mutable_php_metadata_namespace();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.php_metadata_namespace");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string ruby_package = 45;
      case 45:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 106)) {
          auto str = _internal_mutable_ruby_package();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.FileOptions.ruby_package");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* FileOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string java_package = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_java_package().data(), static_cast<int>(this->_internal_java_package().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.java_package");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_java_package(), target);
  }

  // optional string java_outer_classname = 8;
  if (cached_has_bits & 0x00000002u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_java_outer_classname().data(), static_cast<int>(this->_internal_java_outer_classname().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.java_outer_classname");
    target = stream->WriteStringMaybeAliased(
        8, this->_internal_java_outer_classname(), target);
  }

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  if (cached_has_bits & 0x00040000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      9, this->_internal_optimize_for(), target);
  }

  // optional bool java_multiple_files = 10 [default = false];
  if (cached_has_bits & 0x00000400u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(10, this->_internal_java_multiple_files(), target);
  }

  // optional string go_package = 11;
  if (cached_has_bits & 0x00000004u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_go_package().data(), static_cast<int>(this->_internal_go_package().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.go_package");
    target = stream->WriteStringMaybeAliased(
        11, this->_internal_go_package(), target);
  }

  // optional bool cc_generic_services = 16 [default = false];
  if (cached_has_bits & 0x00002000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(16, this->_internal_cc_generic_services(), target);
  }

  // optional bool java_generic_services = 17 [default = false];
  if (cached_has_bits & 0x00004000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(17, this->_internal_java_generic_services(), target);
  }

  // optional bool py_generic_services = 18 [default = false];
  if (cached_has_bits & 0x00008000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(18, this->_internal_py_generic_services(), target);
  }

  // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
  if (cached_has_bits & 0x00000800u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(20, this->_internal_java_generate_equals_and_hash(), target);
  }

  // optional bool deprecated = 23 [default = false];
  if (cached_has_bits & 0x00020000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(23, this->_internal_deprecated(), target);
  }

  // optional bool java_string_check_utf8 = 27 [default = false];
  if (cached_has_bits & 0x00001000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(27, this->_internal_java_string_check_utf8(), target);
  }

  // optional bool cc_enable_arenas = 31 [default = true];
  if (cached_has_bits & 0x00080000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(31, this->_internal_cc_enable_arenas(), target);
  }

  // optional string objc_class_prefix = 36;
  if (cached_has_bits & 0x00000008u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_objc_class_prefix().data(), static_cast<int>(this->_internal_objc_class_prefix().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.objc_class_prefix");
    target = stream->WriteStringMaybeAliased(
        36, this->_internal_objc_class_prefix(), target);
  }

  // optional string csharp_namespace = 37;
  if (cached_has_bits & 0x00000010u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_csharp_namespace().data(), static_cast<int>(this->_internal_csharp_namespace().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.csharp_namespace");
    target = stream->WriteStringMaybeAliased(
        37, this->_internal_csharp_namespace(), target);
  }

  // optional string swift_prefix = 39;
  if (cached_has_bits & 0x00000020u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_swift_prefix().data(), static_cast<int>(this->_internal_swift_prefix().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.swift_prefix");
    target = stream->WriteStringMaybeAliased(
        39, this->_internal_swift_prefix(), target);
  }

  // optional string php_class_prefix = 40;
  if (cached_has_bits & 0x00000040u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_php_class_prefix().data(), static_cast<int>(this->_internal_php_class_prefix().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_class_prefix");
    target = stream->WriteStringMaybeAliased(
        40, this->_internal_php_class_prefix(), target);
  }

  // optional string php_namespace = 41;
  if (cached_has_bits & 0x00000080u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_php_namespace().data(), static_cast<int>(this->_internal_php_namespace().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_namespace");
    target = stream->WriteStringMaybeAliased(
        41, this->_internal_php_namespace(), target);
  }

  // optional bool php_generic_services = 42 [default = false];
  if (cached_has_bits & 0x00010000u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(42, this->_internal_php_generic_services(), target);
  }

  // optional string php_metadata_namespace = 44;
  if (cached_has_bits & 0x00000100u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_php_metadata_namespace().data(), static_cast<int>(this->_internal_php_metadata_namespace().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.php_metadata_namespace");
    target = stream->WriteStringMaybeAliased(
        44, this->_internal_php_metadata_namespace(), target);
  }

  // optional string ruby_package = 45;
  if (cached_has_bits & 0x00000200u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_ruby_package().data(), static_cast<int>(this->_internal_ruby_package().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.FileOptions.ruby_package");
    target = stream->WriteStringMaybeAliased(
        45, this->_internal_ruby_package(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions)
  return target;
}

size_t FileOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x000000ffu) {
    // optional string java_package = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_java_package());
    }

    // optional string java_outer_classname = 8;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_java_outer_classname());
    }

    // optional string go_package = 11;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_go_package());
    }

    // optional string objc_class_prefix = 36;
    if (cached_has_bits & 0x00000008u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_objc_class_prefix());
    }

    // optional string csharp_namespace = 37;
    if (cached_has_bits & 0x00000010u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_csharp_namespace());
    }

    // optional string swift_prefix = 39;
    if (cached_has_bits & 0x00000020u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_swift_prefix());
    }

    // optional string php_class_prefix = 40;
    if (cached_has_bits & 0x00000040u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_php_class_prefix());
    }

    // optional string php_namespace = 41;
    if (cached_has_bits & 0x00000080u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_php_namespace());
    }

  }
  if (cached_has_bits & 0x0000ff00u) {
    // optional string php_metadata_namespace = 44;
    if (cached_has_bits & 0x00000100u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_php_metadata_namespace());
    }

    // optional string ruby_package = 45;
    if (cached_has_bits & 0x00000200u) {
      total_size += 2 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_ruby_package());
    }

    // optional bool java_multiple_files = 10 [default = false];
    if (cached_has_bits & 0x00000400u) {
      total_size += 1 + 1;
    }

    // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
    if (cached_has_bits & 0x00000800u) {
      total_size += 2 + 1;
    }

    // optional bool java_string_check_utf8 = 27 [default = false];
    if (cached_has_bits & 0x00001000u) {
      total_size += 2 + 1;
    }

    // optional bool cc_generic_services = 16 [default = false];
    if (cached_has_bits & 0x00002000u) {
      total_size += 2 + 1;
    }

    // optional bool java_generic_services = 17 [default = false];
    if (cached_has_bits & 0x00004000u) {
      total_size += 2 + 1;
    }

    // optional bool py_generic_services = 18 [default = false];
    if (cached_has_bits & 0x00008000u) {
      total_size += 2 + 1;
    }

  }
  if (cached_has_bits & 0x000f0000u) {
    // optional bool php_generic_services = 42 [default = false];
    if (cached_has_bits & 0x00010000u) {
      total_size += 2 + 1;
    }

    // optional bool deprecated = 23 [default = false];
    if (cached_has_bits & 0x00020000u) {
      total_size += 2 + 1;
    }

    // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    if (cached_has_bits & 0x00040000u) {
      total_size += 1 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_optimize_for());
    }

    // optional bool cc_enable_arenas = 31 [default = true];
    if (cached_has_bits & 0x00080000u) {
      total_size += 2 + 1;
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FileOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    FileOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FileOptions::GetClassData() const { return &_class_data_; }


void FileOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<FileOptions*>(&to_msg);
  auto& from = static_cast<const FileOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x000000ffu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_java_package(from._internal_java_package());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_java_outer_classname(from._internal_java_outer_classname());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_internal_set_go_package(from._internal_go_package());
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_internal_set_objc_class_prefix(from._internal_objc_class_prefix());
    }
    if (cached_has_bits & 0x00000010u) {
      _this->_internal_set_csharp_namespace(from._internal_csharp_namespace());
    }
    if (cached_has_bits & 0x00000020u) {
      _this->_internal_set_swift_prefix(from._internal_swift_prefix());
    }
    if (cached_has_bits & 0x00000040u) {
      _this->_internal_set_php_class_prefix(from._internal_php_class_prefix());
    }
    if (cached_has_bits & 0x00000080u) {
      _this->_internal_set_php_namespace(from._internal_php_namespace());
    }
  }
  if (cached_has_bits & 0x0000ff00u) {
    if (cached_has_bits & 0x00000100u) {
      _this->_internal_set_php_metadata_namespace(from._internal_php_metadata_namespace());
    }
    if (cached_has_bits & 0x00000200u) {
      _this->_internal_set_ruby_package(from._internal_ruby_package());
    }
    if (cached_has_bits & 0x00000400u) {
      _this->_impl_.java_multiple_files_ = from._impl_.java_multiple_files_;
    }
    if (cached_has_bits & 0x00000800u) {
      _this->_impl_.java_generate_equals_and_hash_ = from._impl_.java_generate_equals_and_hash_;
    }
    if (cached_has_bits & 0x00001000u) {
      _this->_impl_.java_string_check_utf8_ = from._impl_.java_string_check_utf8_;
    }
    if (cached_has_bits & 0x00002000u) {
      _this->_impl_.cc_generic_services_ = from._impl_.cc_generic_services_;
    }
    if (cached_has_bits & 0x00004000u) {
      _this->_impl_.java_generic_services_ = from._impl_.java_generic_services_;
    }
    if (cached_has_bits & 0x00008000u) {
      _this->_impl_.py_generic_services_ = from._impl_.py_generic_services_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  if (cached_has_bits & 0x000f0000u) {
    if (cached_has_bits & 0x00010000u) {
      _this->_impl_.php_generic_services_ = from._impl_.php_generic_services_;
    }
    if (cached_has_bits & 0x00020000u) {
      _this->_impl_.deprecated_ = from._impl_.deprecated_;
    }
    if (cached_has_bits & 0x00040000u) {
      _this->_impl_.optimize_for_ = from._impl_.optimize_for_;
    }
    if (cached_has_bits & 0x00080000u) {
      _this->_impl_.cc_enable_arenas_ = from._impl_.cc_enable_arenas_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void FileOptions::CopyFrom(const FileOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FileOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void FileOptions::InternalSwap(FileOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.java_package_, lhs_arena,
      &other->_impl_.java_package_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.java_outer_classname_, lhs_arena,
      &other->_impl_.java_outer_classname_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.go_package_, lhs_arena,
      &other->_impl_.go_package_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.objc_class_prefix_, lhs_arena,
      &other->_impl_.objc_class_prefix_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.csharp_namespace_, lhs_arena,
      &other->_impl_.csharp_namespace_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.swift_prefix_, lhs_arena,
      &other->_impl_.swift_prefix_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.php_class_prefix_, lhs_arena,
      &other->_impl_.php_class_prefix_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.php_namespace_, lhs_arena,
      &other->_impl_.php_namespace_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.php_metadata_namespace_, lhs_arena,
      &other->_impl_.php_metadata_namespace_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.ruby_package_, lhs_arena,
      &other->_impl_.ruby_package_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.deprecated_)
      + sizeof(FileOptions::_impl_.deprecated_)
      - PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.java_multiple_files_)>(
          reinterpret_cast<char*>(&_impl_.java_multiple_files_),
          reinterpret_cast<char*>(&other->_impl_.java_multiple_files_));
  swap(_impl_.optimize_for_, other->_impl_.optimize_for_);
  swap(_impl_.cc_enable_arenas_, other->_impl_.cc_enable_arenas_);
}

::PROTOBUF_NAMESPACE_ID::Metadata FileOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]);
}

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

class MessageOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<MessageOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._has_bits_);
  static void set_has_message_set_wire_format(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_no_standard_descriptor_accessor(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static void set_has_map_entry(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
};

MessageOptions::MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions)
}
MessageOptions::MessageOptions(const MessageOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  MessageOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.message_set_wire_format_){}
    , decltype(_impl_.no_standard_descriptor_accessor_){}
    , decltype(_impl_.deprecated_){}
    , decltype(_impl_.map_entry_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  ::memcpy(&_impl_.message_set_wire_format_, &from._impl_.message_set_wire_format_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.map_entry_) -
    reinterpret_cast<char*>(&_impl_.message_set_wire_format_)) + sizeof(_impl_.map_entry_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
}

inline void MessageOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.message_set_wire_format_){false}
    , decltype(_impl_.no_standard_descriptor_accessor_){false}
    , decltype(_impl_.deprecated_){false}
    , decltype(_impl_.map_entry_){false}
  };
}

MessageOptions::~MessageOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void MessageOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void MessageOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void MessageOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  ::memset(&_impl_.message_set_wire_format_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&_impl_.map_entry_) -
      reinterpret_cast<char*>(&_impl_.message_set_wire_format_)) + sizeof(_impl_.map_entry_));
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* MessageOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional bool message_set_wire_format = 1 [default = false];
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_message_set_wire_format(&has_bits);
          _impl_.message_set_wire_format_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool no_standard_descriptor_accessor = 2 [default = false];
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_no_standard_descriptor_accessor(&has_bits);
          _impl_.no_standard_descriptor_accessor_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool deprecated = 3 [default = false];
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool map_entry = 7;
      case 7:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 56)) {
          _Internal::set_has_map_entry(&has_bits);
          _impl_.map_entry_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* MessageOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional bool message_set_wire_format = 1 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(1, this->_internal_message_set_wire_format(), target);
  }

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_no_standard_descriptor_accessor(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000004u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
  }

  // optional bool map_entry = 7;
  if (cached_has_bits & 0x00000008u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(7, this->_internal_map_entry(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions)
  return target;
}

size_t MessageOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MessageOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    // optional bool message_set_wire_format = 1 [default = false];
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 + 1;
    }

    // optional bool no_standard_descriptor_accessor = 2 [default = false];
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 + 1;
    }

    // optional bool map_entry = 7;
    if (cached_has_bits & 0x00000008u) {
      total_size += 1 + 1;
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MessageOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    MessageOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MessageOptions::GetClassData() const { return &_class_data_; }


void MessageOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<MessageOptions*>(&to_msg);
  auto& from = static_cast<const MessageOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_impl_.message_set_wire_format_ = from._impl_.message_set_wire_format_;
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.no_standard_descriptor_accessor_ = from._impl_.no_standard_descriptor_accessor_;
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.deprecated_ = from._impl_.deprecated_;
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_impl_.map_entry_ = from._impl_.map_entry_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void MessageOptions::CopyFrom(const MessageOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MessageOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessageOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void MessageOptions::InternalSwap(MessageOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.map_entry_)
      + sizeof(MessageOptions::_impl_.map_entry_)
      - PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.message_set_wire_format_)>(
          reinterpret_cast<char*>(&_impl_.message_set_wire_format_),
          reinterpret_cast<char*>(&other->_impl_.message_set_wire_format_));
}

::PROTOBUF_NAMESPACE_ID::Metadata MessageOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]);
}

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

class FieldOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<FieldOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._has_bits_);
  static void set_has_ctype(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_packed(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
  static void set_has_jstype(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_lazy(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
  static void set_has_unverified_lazy(HasBits* has_bits) {
    (*has_bits)[0] |= 16u;
  }
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 32u;
  }
  static void set_has_weak(HasBits* has_bits) {
    (*has_bits)[0] |= 64u;
  }
};

FieldOptions::FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions)
}
FieldOptions::FieldOptions(const FieldOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  FieldOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.ctype_){}
    , decltype(_impl_.jstype_){}
    , decltype(_impl_.packed_){}
    , decltype(_impl_.lazy_){}
    , decltype(_impl_.unverified_lazy_){}
    , decltype(_impl_.deprecated_){}
    , decltype(_impl_.weak_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  ::memcpy(&_impl_.ctype_, &from._impl_.ctype_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.weak_) -
    reinterpret_cast<char*>(&_impl_.ctype_)) + sizeof(_impl_.weak_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
}

inline void FieldOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.ctype_){0}
    , decltype(_impl_.jstype_){0}
    , decltype(_impl_.packed_){false}
    , decltype(_impl_.lazy_){false}
    , decltype(_impl_.unverified_lazy_){false}
    , decltype(_impl_.deprecated_){false}
    , decltype(_impl_.weak_){false}
  };
}

FieldOptions::~FieldOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void FieldOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void FieldOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void FieldOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000007fu) {
    ::memset(&_impl_.ctype_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.weak_) -
        reinterpret_cast<char*>(&_impl_.ctype_)) + sizeof(_impl_.weak_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* FieldOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
          if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldOptions_CType_IsValid(val))) {
            _internal_set_ctype(static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_CType>(val));
          } else {
            ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(1, val, mutable_unknown_fields());
          }
        } else
          goto handle_unusual;
        continue;
      // optional bool packed = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_packed(&has_bits);
          _impl_.packed_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool deprecated = 3 [default = false];
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool lazy = 5 [default = false];
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
          _Internal::set_has_lazy(&has_bits);
          _impl_.lazy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) {
          uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
          if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType_IsValid(val))) {
            _internal_set_jstype(static_cast<::PROTOBUF_NAMESPACE_ID::FieldOptions_JSType>(val));
          } else {
            ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(6, val, mutable_unknown_fields());
          }
        } else
          goto handle_unusual;
        continue;
      // optional bool weak = 10 [default = false];
      case 10:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 80)) {
          _Internal::set_has_weak(&has_bits);
          _impl_.weak_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool unverified_lazy = 15 [default = false];
      case 15:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 120)) {
          _Internal::set_has_unverified_lazy(&has_bits);
          _impl_.unverified_lazy_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* FieldOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      1, this->_internal_ctype(), target);
  }

  // optional bool packed = 2;
  if (cached_has_bits & 0x00000004u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_packed(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000020u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
  }

  // optional bool lazy = 5 [default = false];
  if (cached_has_bits & 0x00000008u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(5, this->_internal_lazy(), target);
  }

  // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      6, this->_internal_jstype(), target);
  }

  // optional bool weak = 10 [default = false];
  if (cached_has_bits & 0x00000040u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(10, this->_internal_weak(), target);
  }

  // optional bool unverified_lazy = 15 [default = false];
  if (cached_has_bits & 0x00000010u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(15, this->_internal_unverified_lazy(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions)
  return target;
}

size_t FieldOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000007fu) {
    // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_ctype());
    }

    // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_jstype());
    }

    // optional bool packed = 2;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 + 1;
    }

    // optional bool lazy = 5 [default = false];
    if (cached_has_bits & 0x00000008u) {
      total_size += 1 + 1;
    }

    // optional bool unverified_lazy = 15 [default = false];
    if (cached_has_bits & 0x00000010u) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (cached_has_bits & 0x00000020u) {
      total_size += 1 + 1;
    }

    // optional bool weak = 10 [default = false];
    if (cached_has_bits & 0x00000040u) {
      total_size += 1 + 1;
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData FieldOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    FieldOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*FieldOptions::GetClassData() const { return &_class_data_; }


void FieldOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<FieldOptions*>(&to_msg);
  auto& from = static_cast<const FieldOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000007fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_impl_.ctype_ = from._impl_.ctype_;
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.jstype_ = from._impl_.jstype_;
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.packed_ = from._impl_.packed_;
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_impl_.lazy_ = from._impl_.lazy_;
    }
    if (cached_has_bits & 0x00000010u) {
      _this->_impl_.unverified_lazy_ = from._impl_.unverified_lazy_;
    }
    if (cached_has_bits & 0x00000020u) {
      _this->_impl_.deprecated_ = from._impl_.deprecated_;
    }
    if (cached_has_bits & 0x00000040u) {
      _this->_impl_.weak_ = from._impl_.weak_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void FieldOptions::CopyFrom(const FieldOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FieldOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void FieldOptions::InternalSwap(FieldOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.weak_)
      + sizeof(FieldOptions::_impl_.weak_)
      - PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.ctype_)>(
          reinterpret_cast<char*>(&_impl_.ctype_),
          reinterpret_cast<char*>(&other->_impl_.ctype_));
}

::PROTOBUF_NAMESPACE_ID::Metadata FieldOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]);
}

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

class OneofOptions::_Internal {
 public:
};

OneofOptions::OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions)
}
OneofOptions::OneofOptions(const OneofOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  OneofOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
}

inline void OneofOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_.uninterpreted_option_){arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

OneofOptions::~OneofOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void OneofOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void OneofOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void OneofOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* OneofOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* OneofOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions)
  return target;
}

size_t OneofOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData OneofOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    OneofOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*OneofOptions::GetClassData() const { return &_class_data_; }


void OneofOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<OneofOptions*>(&to_msg);
  auto& from = static_cast<const OneofOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void OneofOptions::CopyFrom(const OneofOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool OneofOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void OneofOptions::InternalSwap(OneofOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
}

::PROTOBUF_NAMESPACE_ID::Metadata OneofOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]);
}

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

class EnumOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<EnumOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._has_bits_);
  static void set_has_allow_alias(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

EnumOptions::EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions)
}
EnumOptions::EnumOptions(const EnumOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  EnumOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.allow_alias_){}
    , decltype(_impl_.deprecated_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  ::memcpy(&_impl_.allow_alias_, &from._impl_.allow_alias_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.deprecated_) -
    reinterpret_cast<char*>(&_impl_.allow_alias_)) + sizeof(_impl_.deprecated_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
}

inline void EnumOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.allow_alias_){false}
    , decltype(_impl_.deprecated_){false}
  };
}

EnumOptions::~EnumOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void EnumOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void EnumOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void EnumOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  ::memset(&_impl_.allow_alias_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&_impl_.deprecated_) -
      reinterpret_cast<char*>(&_impl_.allow_alias_)) + sizeof(_impl_.deprecated_));
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* EnumOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional bool allow_alias = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_allow_alias(&has_bits);
          _impl_.allow_alias_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional bool deprecated = 3 [default = false];
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* EnumOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional bool allow_alias = 2;
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_allow_alias(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(3, this->_internal_deprecated(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions)
  return target;
}

size_t EnumOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional bool allow_alias = 2;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 + 1;
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    EnumOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumOptions::GetClassData() const { return &_class_data_; }


void EnumOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<EnumOptions*>(&to_msg);
  auto& from = static_cast<const EnumOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_impl_.allow_alias_ = from._impl_.allow_alias_;
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.deprecated_ = from._impl_.deprecated_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void EnumOptions::CopyFrom(const EnumOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void EnumOptions::InternalSwap(EnumOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.deprecated_)
      + sizeof(EnumOptions::_impl_.deprecated_)
      - PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.allow_alias_)>(
          reinterpret_cast<char*>(&_impl_.allow_alias_),
          reinterpret_cast<char*>(&other->_impl_.allow_alias_));
}

::PROTOBUF_NAMESPACE_ID::Metadata EnumOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]);
}

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

class EnumValueOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<EnumValueOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._has_bits_);
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
};

EnumValueOptions::EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions)
}
EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  EnumValueOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.deprecated_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_impl_.deprecated_ = from._impl_.deprecated_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
}

inline void EnumValueOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.deprecated_){false}
  };
}

EnumValueOptions::~EnumValueOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void EnumValueOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void EnumValueOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void EnumValueOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  _impl_.deprecated_ = false;
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* EnumValueOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional bool deprecated = 1 [default = false];
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* EnumValueOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional bool deprecated = 1 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(1, this->_internal_deprecated(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions)
  return target;
}

size_t EnumValueOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // optional bool deprecated = 1 [default = false];
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    total_size += 1 + 1;
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData EnumValueOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    EnumValueOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*EnumValueOptions::GetClassData() const { return &_class_data_; }


void EnumValueOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<EnumValueOptions*>(&to_msg);
  auto& from = static_cast<const EnumValueOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  if (from._internal_has_deprecated()) {
    _this->_internal_set_deprecated(from._internal_deprecated());
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumValueOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void EnumValueOptions::InternalSwap(EnumValueOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  swap(_impl_.deprecated_, other->_impl_.deprecated_);
}

::PROTOBUF_NAMESPACE_ID::Metadata EnumValueOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]);
}

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

class ServiceOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<ServiceOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._has_bits_);
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
};

ServiceOptions::ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions)
}
ServiceOptions::ServiceOptions(const ServiceOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  ServiceOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.deprecated_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_impl_.deprecated_ = from._impl_.deprecated_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
}

inline void ServiceOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.deprecated_){false}
  };
}

ServiceOptions::~ServiceOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void ServiceOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void ServiceOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void ServiceOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  _impl_.deprecated_ = false;
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* ServiceOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional bool deprecated = 33 [default = false];
      case 33:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* ServiceOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional bool deprecated = 33 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions)
  return target;
}

size_t ServiceOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  // optional bool deprecated = 33 [default = false];
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    total_size += 2 + 1;
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData ServiceOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    ServiceOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*ServiceOptions::GetClassData() const { return &_class_data_; }


void ServiceOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<ServiceOptions*>(&to_msg);
  auto& from = static_cast<const ServiceOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  if (from._internal_has_deprecated()) {
    _this->_internal_set_deprecated(from._internal_deprecated());
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void ServiceOptions::CopyFrom(const ServiceOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ServiceOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void ServiceOptions::InternalSwap(ServiceOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  swap(_impl_.deprecated_, other->_impl_.deprecated_);
}

::PROTOBUF_NAMESPACE_ID::Metadata ServiceOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]);
}

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

class MethodOptions::_Internal {
 public:
  using HasBits = decltype(std::declval<MethodOptions>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._has_bits_);
  static void set_has_deprecated(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_idempotency_level(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

MethodOptions::MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions)
}
MethodOptions::MethodOptions(const MethodOptions& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  MethodOptions* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{}
    , decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){from._impl_.uninterpreted_option_}
    , decltype(_impl_.deprecated_){}
    , decltype(_impl_.idempotency_level_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  ::memcpy(&_impl_.deprecated_, &from._impl_.deprecated_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.idempotency_level_) -
    reinterpret_cast<char*>(&_impl_.deprecated_)) + sizeof(_impl_.idempotency_level_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
}

inline void MethodOptions::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      /*decltype(_impl_._extensions_)*/{::_pbi::ArenaInitialized(), arena}
    , decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.uninterpreted_option_){arena}
    , decltype(_impl_.deprecated_){false}
    , decltype(_impl_.idempotency_level_){0}
  };
}

MethodOptions::~MethodOptions() {
  // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void MethodOptions::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_._extensions_.~ExtensionSet();
  _impl_.uninterpreted_option_.~RepeatedPtrField();
}

void MethodOptions::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void MethodOptions::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_._extensions_.Clear();
  _impl_.uninterpreted_option_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    ::memset(&_impl_.deprecated_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.idempotency_level_) -
        reinterpret_cast<char*>(&_impl_.deprecated_)) + sizeof(_impl_.idempotency_level_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* MethodOptions::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // optional bool deprecated = 33 [default = false];
      case 33:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 8)) {
          _Internal::set_has_deprecated(&has_bits);
          _impl_.deprecated_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
      case 34:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
          if (PROTOBUF_PREDICT_TRUE(::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel_IsValid(val))) {
            _internal_set_idempotency_level(static_cast<::PROTOBUF_NAMESPACE_ID::MethodOptions_IdempotencyLevel>(val));
          } else {
            ::PROTOBUF_NAMESPACE_ID::internal::WriteVarint(34, val, mutable_unknown_fields());
          }
        } else
          goto handle_unusual;
        continue;
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          ptr -= 2;
          do {
            ptr += 2;
            ptr = ctx->ParseMessage(_internal_add_uninterpreted_option(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<7994>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    if ((8000u <= tag)) {
      ptr = _impl_._extensions_.ParseField(tag, ptr, internal_default_instance(), &_internal_metadata_, ctx);
      CHK_(ptr != nullptr);
      continue;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* MethodOptions::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional bool deprecated = 33 [default = false];
  if (cached_has_bits & 0x00000001u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(33, this->_internal_deprecated(), target);
  }

  // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
      34, this->_internal_idempotency_level(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_uninterpreted_option_size()); i < n; i++) {
    const auto& repfield = this->_internal_uninterpreted_option(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(999, repfield, repfield.GetCachedSize(), target, stream);
  }

  // Extension range [1000, 536870912)
  target = _impl_._extensions_._InternalSerialize(
  internal_default_instance(), 1000, 536870912, target, stream);

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions)
  return target;
}

size_t MethodOptions::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodOptions)
  size_t total_size = 0;

  total_size += _impl_._extensions_.ByteSize();

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2UL * this->_internal_uninterpreted_option_size();
  for (const auto& msg : this->_impl_.uninterpreted_option_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional bool deprecated = 33 [default = false];
    if (cached_has_bits & 0x00000001u) {
      total_size += 2 + 1;
    }

    // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
    if (cached_has_bits & 0x00000002u) {
      total_size += 2 +
        ::_pbi::WireFormatLite::EnumSize(this->_internal_idempotency_level());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData MethodOptions::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    MethodOptions::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*MethodOptions::GetClassData() const { return &_class_data_; }


void MethodOptions::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<MethodOptions*>(&to_msg);
  auto& from = static_cast<const MethodOptions&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.uninterpreted_option_.MergeFrom(from._impl_.uninterpreted_option_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_impl_.deprecated_ = from._impl_.deprecated_;
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.idempotency_level_ = from._impl_.idempotency_level_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void MethodOptions::CopyFrom(const MethodOptions& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodOptions)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MethodOptions::IsInitialized() const {
  if (!_impl_._extensions_.IsInitialized()) {
    return false;
  }

  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.uninterpreted_option_))
    return false;
  return true;
}

void MethodOptions::InternalSwap(MethodOptions* other) {
  using std::swap;
  _impl_._extensions_.InternalSwap(&other->_impl_._extensions_);
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_);
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.idempotency_level_)
      + sizeof(MethodOptions::_impl_.idempotency_level_)
      - PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.deprecated_)>(
          reinterpret_cast<char*>(&_impl_.deprecated_),
          reinterpret_cast<char*>(&other->_impl_.deprecated_));
}

::PROTOBUF_NAMESPACE_ID::Metadata MethodOptions::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]);
}

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

class UninterpretedOption_NamePart::_Internal {
 public:
  using HasBits = decltype(std::declval<UninterpretedOption_NamePart>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._has_bits_);
  static void set_has_name_part(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_is_extension(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static bool MissingRequiredFields(const HasBits& has_bits) {
    return ((has_bits[0] & 0x00000003) ^ 0x00000003) != 0;
  }
};

UninterpretedOption_NamePart::UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart)
}
UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  UninterpretedOption_NamePart* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_part_){}
    , decltype(_impl_.is_extension_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.name_part_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_part_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_name_part()) {
    _this->_impl_.name_part_.Set(from._internal_name_part(), 
      _this->GetArenaForAllocation());
  }
  _this->_impl_.is_extension_ = from._impl_.is_extension_;
  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
}

inline void UninterpretedOption_NamePart::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_part_){}
    , decltype(_impl_.is_extension_){false}
  };
  _impl_.name_part_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.name_part_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void UninterpretedOption_NamePart::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.name_part_.Destroy();
}

void UninterpretedOption_NamePart::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void UninterpretedOption_NamePart::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    _impl_.name_part_.ClearNonDefaultToEmpty();
  }
  _impl_.is_extension_ = false;
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // required string name_part = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          auto str = _internal_mutable_name_part();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.UninterpretedOption.NamePart.name_part");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // required bool is_extension = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 16)) {
          _Internal::set_has_is_extension(&has_bits);
          _impl_.is_extension_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* UninterpretedOption_NamePart::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // required string name_part = 1;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_name_part().data(), static_cast<int>(this->_internal_name_part().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.NamePart.name_part");
    target = stream->WriteStringMaybeAliased(
        1, this->_internal_name_part(), target);
  }

  // required bool is_extension = 2;
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(2, this->_internal_is_extension(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart)
  return target;
}

size_t UninterpretedOption_NamePart::RequiredFieldsByteSizeFallback() const {
// @@protoc_insertion_point(required_fields_byte_size_fallback_start:google.protobuf.UninterpretedOption.NamePart)
  size_t total_size = 0;

  if (_internal_has_name_part()) {
    // required string name_part = 1;
    total_size += 1 +
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
        this->_internal_name_part());
  }

  if (_internal_has_is_extension()) {
    // required bool is_extension = 2;
    total_size += 1 + 1;
  }

  return total_size;
}
size_t UninterpretedOption_NamePart::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption.NamePart)
  size_t total_size = 0;

  if (((_impl_._has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) {  // All required fields are present.
    // required string name_part = 1;
    total_size += 1 +
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
        this->_internal_name_part());

    // required bool is_extension = 2;
    total_size += 1 + 1;

  } else {
    total_size += RequiredFieldsByteSizeFallback();
  }
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption_NamePart::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    UninterpretedOption_NamePart::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption_NamePart::GetClassData() const { return &_class_data_; }


void UninterpretedOption_NamePart::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<UninterpretedOption_NamePart*>(&to_msg);
  auto& from = static_cast<const UninterpretedOption_NamePart&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name_part(from._internal_name_part());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.is_extension_ = from._impl_.is_extension_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption.NamePart)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool UninterpretedOption_NamePart::IsInitialized() const {
  if (_Internal::MissingRequiredFields(_impl_._has_bits_)) return false;
  return true;
}

void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.name_part_, lhs_arena,
      &other->_impl_.name_part_, rhs_arena
  );
  swap(_impl_.is_extension_, other->_impl_.is_extension_);
}

::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption_NamePart::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]);
}

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

class UninterpretedOption::_Internal {
 public:
  using HasBits = decltype(std::declval<UninterpretedOption>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._has_bits_);
  static void set_has_identifier_value(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_positive_int_value(HasBits* has_bits) {
    (*has_bits)[0] |= 8u;
  }
  static void set_has_negative_int_value(HasBits* has_bits) {
    (*has_bits)[0] |= 16u;
  }
  static void set_has_double_value(HasBits* has_bits) {
    (*has_bits)[0] |= 32u;
  }
  static void set_has_string_value(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_aggregate_value(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
};

UninterpretedOption::UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption)
}
UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  UninterpretedOption* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){from._impl_.name_}
    , decltype(_impl_.identifier_value_){}
    , decltype(_impl_.string_value_){}
    , decltype(_impl_.aggregate_value_){}
    , decltype(_impl_.positive_int_value_){}
    , decltype(_impl_.negative_int_value_){}
    , decltype(_impl_.double_value_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.identifier_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.identifier_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_identifier_value()) {
    _this->_impl_.identifier_value_.Set(from._internal_identifier_value(), 
      _this->GetArenaForAllocation());
  }
  _impl_.string_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.string_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_string_value()) {
    _this->_impl_.string_value_.Set(from._internal_string_value(), 
      _this->GetArenaForAllocation());
  }
  _impl_.aggregate_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.aggregate_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_aggregate_value()) {
    _this->_impl_.aggregate_value_.Set(from._internal_aggregate_value(), 
      _this->GetArenaForAllocation());
  }
  ::memcpy(&_impl_.positive_int_value_, &from._impl_.positive_int_value_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.double_value_) -
    reinterpret_cast<char*>(&_impl_.positive_int_value_)) + sizeof(_impl_.double_value_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
}

inline void UninterpretedOption::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.name_){arena}
    , decltype(_impl_.identifier_value_){}
    , decltype(_impl_.string_value_){}
    , decltype(_impl_.aggregate_value_){}
    , decltype(_impl_.positive_int_value_){uint64_t{0u}}
    , decltype(_impl_.negative_int_value_){int64_t{0}}
    , decltype(_impl_.double_value_){0}
  };
  _impl_.identifier_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.identifier_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.string_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.string_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.aggregate_value_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.aggregate_value_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

UninterpretedOption::~UninterpretedOption() {
  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void UninterpretedOption::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.name_.~RepeatedPtrField();
  _impl_.identifier_value_.Destroy();
  _impl_.string_value_.Destroy();
  _impl_.aggregate_value_.Destroy();
}

void UninterpretedOption::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void UninterpretedOption::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.name_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.identifier_value_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.string_value_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      _impl_.aggregate_value_.ClearNonDefaultToEmpty();
    }
  }
  if (cached_has_bits & 0x00000038u) {
    ::memset(&_impl_.positive_int_value_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.double_value_) -
        reinterpret_cast<char*>(&_impl_.positive_int_value_)) + sizeof(_impl_.double_value_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* UninterpretedOption::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_name(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<18>(ptr));
        } else
          goto handle_unusual;
        continue;
      // optional string identifier_value = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          auto str = _internal_mutable_identifier_value();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.UninterpretedOption.identifier_value");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional uint64 positive_int_value = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
          _Internal::set_has_positive_int_value(&has_bits);
          _impl_.positive_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional int64 negative_int_value = 5;
      case 5:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 40)) {
          _Internal::set_has_negative_int_value(&has_bits);
          _impl_.negative_int_value_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional double double_value = 6;
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 49)) {
          _Internal::set_has_double_value(&has_bits);
          _impl_.double_value_ = ::PROTOBUF_NAMESPACE_ID::internal::UnalignedLoad<double>(ptr);
          ptr += sizeof(double);
        } else
          goto handle_unusual;
        continue;
      // optional bytes string_value = 7;
      case 7:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 58)) {
          auto str = _internal_mutable_string_value();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string aggregate_value = 8;
      case 8:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 66)) {
          auto str = _internal_mutable_aggregate_value();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.UninterpretedOption.aggregate_value");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* UninterpretedOption::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_name_size()); i < n; i++) {
    const auto& repfield = this->_internal_name(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(2, repfield, repfield.GetCachedSize(), target, stream);
  }

  cached_has_bits = _impl_._has_bits_[0];
  // optional string identifier_value = 3;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_identifier_value().data(), static_cast<int>(this->_internal_identifier_value().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.identifier_value");
    target = stream->WriteStringMaybeAliased(
        3, this->_internal_identifier_value(), target);
  }

  // optional uint64 positive_int_value = 4;
  if (cached_has_bits & 0x00000008u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteUInt64ToArray(4, this->_internal_positive_int_value(), target);
  }

  // optional int64 negative_int_value = 5;
  if (cached_has_bits & 0x00000010u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt64ToArray(5, this->_internal_negative_int_value(), target);
  }

  // optional double double_value = 6;
  if (cached_has_bits & 0x00000020u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteDoubleToArray(6, this->_internal_double_value(), target);
  }

  // optional bytes string_value = 7;
  if (cached_has_bits & 0x00000002u) {
    target = stream->WriteBytesMaybeAliased(
        7, this->_internal_string_value(), target);
  }

  // optional string aggregate_value = 8;
  if (cached_has_bits & 0x00000004u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_aggregate_value().data(), static_cast<int>(this->_internal_aggregate_value().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.UninterpretedOption.aggregate_value");
    target = stream->WriteStringMaybeAliased(
        8, this->_internal_aggregate_value(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption)
  return target;
}

size_t UninterpretedOption::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  total_size += 1UL * this->_internal_name_size();
  for (const auto& msg : this->_impl_.name_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000003fu) {
    // optional string identifier_value = 3;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_identifier_value());
    }

    // optional bytes string_value = 7;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize(
          this->_internal_string_value());
    }

    // optional string aggregate_value = 8;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_aggregate_value());
    }

    // optional uint64 positive_int_value = 4;
    if (cached_has_bits & 0x00000008u) {
      total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_positive_int_value());
    }

    // optional int64 negative_int_value = 5;
    if (cached_has_bits & 0x00000010u) {
      total_size += ::_pbi::WireFormatLite::Int64SizePlusOne(this->_internal_negative_int_value());
    }

    // optional double double_value = 6;
    if (cached_has_bits & 0x00000020u) {
      total_size += 1 + 8;
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData UninterpretedOption::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    UninterpretedOption::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*UninterpretedOption::GetClassData() const { return &_class_data_; }


void UninterpretedOption::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<UninterpretedOption*>(&to_msg);
  auto& from = static_cast<const UninterpretedOption&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.name_.MergeFrom(from._impl_.name_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000003fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_identifier_value(from._internal_identifier_value());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_string_value(from._internal_string_value());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_internal_set_aggregate_value(from._internal_aggregate_value());
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_impl_.positive_int_value_ = from._impl_.positive_int_value_;
    }
    if (cached_has_bits & 0x00000010u) {
      _this->_impl_.negative_int_value_ = from._impl_.negative_int_value_;
    }
    if (cached_has_bits & 0x00000020u) {
      _this->_impl_.double_value_ = from._impl_.double_value_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool UninterpretedOption::IsInitialized() const {
  if (!::PROTOBUF_NAMESPACE_ID::internal::AllAreInitialized(_impl_.name_))
    return false;
  return true;
}

void UninterpretedOption::InternalSwap(UninterpretedOption* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.name_.InternalSwap(&other->_impl_.name_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.identifier_value_, lhs_arena,
      &other->_impl_.identifier_value_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.string_value_, lhs_arena,
      &other->_impl_.string_value_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.aggregate_value_, lhs_arena,
      &other->_impl_.aggregate_value_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.double_value_)
      + sizeof(UninterpretedOption::_impl_.double_value_)
      - PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.positive_int_value_)>(
          reinterpret_cast<char*>(&_impl_.positive_int_value_),
          reinterpret_cast<char*>(&other->_impl_.positive_int_value_));
}

::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]);
}

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

class SourceCodeInfo_Location::_Internal {
 public:
  using HasBits = decltype(std::declval<SourceCodeInfo_Location>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._has_bits_);
  static void set_has_leading_comments(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_trailing_comments(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
};

SourceCodeInfo_Location::SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location)
}
SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  SourceCodeInfo_Location* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.path_){from._impl_.path_}
    , /*decltype(_impl_._path_cached_byte_size_)*/{0}
    , decltype(_impl_.span_){from._impl_.span_}
    , /*decltype(_impl_._span_cached_byte_size_)*/{0}
    , decltype(_impl_.leading_detached_comments_){from._impl_.leading_detached_comments_}
    , decltype(_impl_.leading_comments_){}
    , decltype(_impl_.trailing_comments_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.leading_comments_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.leading_comments_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_leading_comments()) {
    _this->_impl_.leading_comments_.Set(from._internal_leading_comments(), 
      _this->GetArenaForAllocation());
  }
  _impl_.trailing_comments_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.trailing_comments_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_trailing_comments()) {
    _this->_impl_.trailing_comments_.Set(from._internal_trailing_comments(), 
      _this->GetArenaForAllocation());
  }
  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
}

inline void SourceCodeInfo_Location::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.path_){arena}
    , /*decltype(_impl_._path_cached_byte_size_)*/{0}
    , decltype(_impl_.span_){arena}
    , /*decltype(_impl_._span_cached_byte_size_)*/{0}
    , decltype(_impl_.leading_detached_comments_){arena}
    , decltype(_impl_.leading_comments_){}
    , decltype(_impl_.trailing_comments_){}
  };
  _impl_.leading_comments_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.leading_comments_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.trailing_comments_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.trailing_comments_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

SourceCodeInfo_Location::~SourceCodeInfo_Location() {
  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void SourceCodeInfo_Location::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.path_.~RepeatedField();
  _impl_.span_.~RepeatedField();
  _impl_.leading_detached_comments_.~RepeatedPtrField();
  _impl_.leading_comments_.Destroy();
  _impl_.trailing_comments_.Destroy();
}

void SourceCodeInfo_Location::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void SourceCodeInfo_Location::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.path_.Clear();
  _impl_.span_.Clear();
  _impl_.leading_detached_comments_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.leading_comments_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.trailing_comments_.ClearNonDefaultToEmpty();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated int32 path = 1 [packed = true];
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_path(), ptr, ctx);
          CHK_(ptr);
        } else if (static_cast<uint8_t>(tag) == 8) {
          _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // repeated int32 span = 2 [packed = true];
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_span(), ptr, ctx);
          CHK_(ptr);
        } else if (static_cast<uint8_t>(tag) == 16) {
          _internal_add_span(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string leading_comments = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
          auto str = _internal_mutable_leading_comments();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_comments");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional string trailing_comments = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
          auto str = _internal_mutable_trailing_comments();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.trailing_comments");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // repeated string leading_detached_comments = 6;
      case 6:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 50)) {
          ptr -= 1;
          do {
            ptr += 1;
            auto str = _internal_add_leading_detached_comments();
            ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
            CHK_(ptr);
            #ifndef NDEBUG
            ::_pbi::VerifyUTF8(str, "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
            #endif  // !NDEBUG
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<50>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* SourceCodeInfo_Location::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated int32 path = 1 [packed = true];
  {
    int byte_size = _impl_._path_cached_byte_size_.load(std::memory_order_relaxed);
    if (byte_size > 0) {
      target = stream->WriteInt32Packed(
          1, _internal_path(), byte_size, target);
    }
  }

  // repeated int32 span = 2 [packed = true];
  {
    int byte_size = _impl_._span_cached_byte_size_.load(std::memory_order_relaxed);
    if (byte_size > 0) {
      target = stream->WriteInt32Packed(
          2, _internal_span(), byte_size, target);
    }
  }

  cached_has_bits = _impl_._has_bits_[0];
  // optional string leading_comments = 3;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_leading_comments().data(), static_cast<int>(this->_internal_leading_comments().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.leading_comments");
    target = stream->WriteStringMaybeAliased(
        3, this->_internal_leading_comments(), target);
  }

  // optional string trailing_comments = 4;
  if (cached_has_bits & 0x00000002u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_trailing_comments().data(), static_cast<int>(this->_internal_trailing_comments().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.trailing_comments");
    target = stream->WriteStringMaybeAliased(
        4, this->_internal_trailing_comments(), target);
  }

  // repeated string leading_detached_comments = 6;
  for (int i = 0, n = this->_internal_leading_detached_comments_size(); i < n; i++) {
    const auto& s = this->_internal_leading_detached_comments(i);
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      s.data(), static_cast<int>(s.length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
    target = stream->WriteString(6, s, target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location)
  return target;
}

size_t SourceCodeInfo_Location::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo.Location)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated int32 path = 1 [packed = true];
  {
    size_t data_size = ::_pbi::WireFormatLite::
      Int32Size(this->_impl_.path_);
    if (data_size > 0) {
      total_size += 1 +
        ::_pbi::WireFormatLite::Int32Size(static_cast<int32_t>(data_size));
    }
    int cached_size = ::_pbi::ToCachedSize(data_size);
    _impl_._path_cached_byte_size_.store(cached_size,
                                    std::memory_order_relaxed);
    total_size += data_size;
  }

  // repeated int32 span = 2 [packed = true];
  {
    size_t data_size = ::_pbi::WireFormatLite::
      Int32Size(this->_impl_.span_);
    if (data_size > 0) {
      total_size += 1 +
        ::_pbi::WireFormatLite::Int32Size(static_cast<int32_t>(data_size));
    }
    int cached_size = ::_pbi::ToCachedSize(data_size);
    _impl_._span_cached_byte_size_.store(cached_size,
                                    std::memory_order_relaxed);
    total_size += data_size;
  }

  // repeated string leading_detached_comments = 6;
  total_size += 1 *
      ::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(_impl_.leading_detached_comments_.size());
  for (int i = 0, n = _impl_.leading_detached_comments_.size(); i < n; i++) {
    total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
      _impl_.leading_detached_comments_.Get(i));
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional string leading_comments = 3;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_leading_comments());
    }

    // optional string trailing_comments = 4;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_trailing_comments());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo_Location::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    SourceCodeInfo_Location::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo_Location::GetClassData() const { return &_class_data_; }


void SourceCodeInfo_Location::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<SourceCodeInfo_Location*>(&to_msg);
  auto& from = static_cast<const SourceCodeInfo_Location&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.path_.MergeFrom(from._impl_.path_);
  _this->_impl_.span_.MergeFrom(from._impl_.span_);
  _this->_impl_.leading_detached_comments_.MergeFrom(from._impl_.leading_detached_comments_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_leading_comments(from._internal_leading_comments());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_trailing_comments(from._internal_trailing_comments());
    }
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo.Location)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SourceCodeInfo_Location::IsInitialized() const {
  return true;
}

void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.path_.InternalSwap(&other->_impl_.path_);
  _impl_.span_.InternalSwap(&other->_impl_.span_);
  _impl_.leading_detached_comments_.InternalSwap(&other->_impl_.leading_detached_comments_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.leading_comments_, lhs_arena,
      &other->_impl_.leading_comments_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.trailing_comments_, lhs_arena,
      &other->_impl_.trailing_comments_, rhs_arena
  );
}

::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo_Location::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]);
}

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

class SourceCodeInfo::_Internal {
 public:
};

SourceCodeInfo::SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo)
}
SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  SourceCodeInfo* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_.location_){from._impl_.location_}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
}

inline void SourceCodeInfo::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_.location_){arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

SourceCodeInfo::~SourceCodeInfo() {
  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void SourceCodeInfo::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.location_.~RepeatedPtrField();
}

void SourceCodeInfo::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void SourceCodeInfo::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.location_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* SourceCodeInfo::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_location(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* SourceCodeInfo::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_location_size()); i < n; i++) {
    const auto& repfield = this->_internal_location(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo)
  return target;
}

size_t SourceCodeInfo::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  total_size += 1UL * this->_internal_location_size();
  for (const auto& msg : this->_impl_.location_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData SourceCodeInfo::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    SourceCodeInfo::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*SourceCodeInfo::GetClassData() const { return &_class_data_; }


void SourceCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<SourceCodeInfo*>(&to_msg);
  auto& from = static_cast<const SourceCodeInfo&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.location_.MergeFrom(from._impl_.location_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SourceCodeInfo::IsInitialized() const {
  return true;
}

void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.location_.InternalSwap(&other->_impl_.location_);
}

::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]);
}

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

class GeneratedCodeInfo_Annotation::_Internal {
 public:
  using HasBits = decltype(std::declval<GeneratedCodeInfo_Annotation>()._impl_._has_bits_);
  static constexpr int32_t kHasBitsOffset =
    8 * PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._has_bits_);
  static void set_has_source_file(HasBits* has_bits) {
    (*has_bits)[0] |= 1u;
  }
  static void set_has_begin(HasBits* has_bits) {
    (*has_bits)[0] |= 2u;
  }
  static void set_has_end(HasBits* has_bits) {
    (*has_bits)[0] |= 4u;
  }
};

GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
}
GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  GeneratedCodeInfo_Annotation* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){from._impl_._has_bits_}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.path_){from._impl_.path_}
    , /*decltype(_impl_._path_cached_byte_size_)*/{0}
    , decltype(_impl_.source_file_){}
    , decltype(_impl_.begin_){}
    , decltype(_impl_.end_){}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  _impl_.source_file_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.source_file_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (from._internal_has_source_file()) {
    _this->_impl_.source_file_.Set(from._internal_source_file(), 
      _this->GetArenaForAllocation());
  }
  ::memcpy(&_impl_.begin_, &from._impl_.begin_,
    static_cast<size_t>(reinterpret_cast<char*>(&_impl_.end_) -
    reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.end_));
  // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
}

inline void GeneratedCodeInfo_Annotation::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_._has_bits_){}
    , /*decltype(_impl_._cached_size_)*/{}
    , decltype(_impl_.path_){arena}
    , /*decltype(_impl_._path_cached_byte_size_)*/{0}
    , decltype(_impl_.source_file_){}
    , decltype(_impl_.begin_){0}
    , decltype(_impl_.end_){0}
  };
  _impl_.source_file_.InitDefault();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
    _impl_.source_file_.Set("", GetArenaForAllocation());
  #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
}

GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() {
  // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void GeneratedCodeInfo_Annotation::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.path_.~RepeatedField();
  _impl_.source_file_.Destroy();
}

void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void GeneratedCodeInfo_Annotation::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.path_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    _impl_.source_file_.ClearNonDefaultToEmpty();
  }
  if (cached_has_bits & 0x00000006u) {
    ::memset(&_impl_.begin_, 0, static_cast<size_t>(
        reinterpret_cast<char*>(&_impl_.end_) -
        reinterpret_cast<char*>(&_impl_.begin_)) + sizeof(_impl_.end_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  _Internal::HasBits has_bits{};
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated int32 path = 1 [packed = true];
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr = ::PROTOBUF_NAMESPACE_ID::internal::PackedInt32Parser(_internal_mutable_path(), ptr, ctx);
          CHK_(ptr);
        } else if (static_cast<uint8_t>(tag) == 8) {
          _internal_add_path(::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr));
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional string source_file = 2;
      case 2:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
          auto str = _internal_mutable_source_file();
          ptr = ::_pbi::InlineGreedyStringParser(str, ptr, ctx);
          CHK_(ptr);
          #ifndef NDEBUG
          ::_pbi::VerifyUTF8(str, "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
          #endif  // !NDEBUG
        } else
          goto handle_unusual;
        continue;
      // optional int32 begin = 3;
      case 3:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
          _Internal::set_has_begin(&has_bits);
          _impl_.begin_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      // optional int32 end = 4;
      case 4:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 32)) {
          _Internal::set_has_end(&has_bits);
          _impl_.end_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
          CHK_(ptr);
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  _impl_._has_bits_.Or(has_bits);
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* GeneratedCodeInfo_Annotation::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated int32 path = 1 [packed = true];
  {
    int byte_size = _impl_._path_cached_byte_size_.load(std::memory_order_relaxed);
    if (byte_size > 0) {
      target = stream->WriteInt32Packed(
          1, _internal_path(), byte_size, target);
    }
  }

  cached_has_bits = _impl_._has_bits_[0];
  // optional string source_file = 2;
  if (cached_has_bits & 0x00000001u) {
    ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::VerifyUTF8StringNamedField(
      this->_internal_source_file().data(), static_cast<int>(this->_internal_source_file().length()),
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SERIALIZE,
      "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
    target = stream->WriteStringMaybeAliased(
        2, this->_internal_source_file(), target);
  }

  // optional int32 begin = 3;
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(3, this->_internal_begin(), target);
  }

  // optional int32 end = 4;
  if (cached_has_bits & 0x00000004u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteInt32ToArray(4, this->_internal_end(), target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation)
  return target;
}

size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo.Annotation)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated int32 path = 1 [packed = true];
  {
    size_t data_size = ::_pbi::WireFormatLite::
      Int32Size(this->_impl_.path_);
    if (data_size > 0) {
      total_size += 1 +
        ::_pbi::WireFormatLite::Int32Size(static_cast<int32_t>(data_size));
    }
    int cached_size = ::_pbi::ToCachedSize(data_size);
    _impl_._path_cached_byte_size_.store(cached_size,
                                    std::memory_order_relaxed);
    total_size += data_size;
  }

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    // optional string source_file = 2;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 +
        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
          this->_internal_source_file());
    }

    // optional int32 begin = 3;
    if (cached_has_bits & 0x00000002u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_begin());
    }

    // optional int32 end = 4;
    if (cached_has_bits & 0x00000004u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this->_internal_end());
    }

  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo_Annotation::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    GeneratedCodeInfo_Annotation::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo_Annotation::GetClassData() const { return &_class_data_; }


void GeneratedCodeInfo_Annotation::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<GeneratedCodeInfo_Annotation*>(&to_msg);
  auto& from = static_cast<const GeneratedCodeInfo_Annotation&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.path_.MergeFrom(from._impl_.path_);
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000007u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_source_file(from._internal_source_file());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.begin_ = from._impl_.begin_;
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.end_ = from._impl_.end_;
    }
    _this->_impl_._has_bits_[0] |= cached_has_bits;
  }
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void GeneratedCodeInfo_Annotation::CopyFrom(const GeneratedCodeInfo_Annotation& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool GeneratedCodeInfo_Annotation::IsInitialized() const {
  return true;
}

void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) {
  using std::swap;
  auto* lhs_arena = GetArenaForAllocation();
  auto* rhs_arena = other->GetArenaForAllocation();
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.path_.InternalSwap(&other->_impl_.path_);
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
      &_impl_.source_file_, lhs_arena,
      &other->_impl_.source_file_, rhs_arena
  );
  ::PROTOBUF_NAMESPACE_ID::internal::memswap<
      PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.end_)
      + sizeof(GeneratedCodeInfo_Annotation::_impl_.end_)
      - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.begin_)>(
          reinterpret_cast<char*>(&_impl_.begin_),
          reinterpret_cast<char*>(&other->_impl_.begin_));
}

::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]);
}

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

class GeneratedCodeInfo::_Internal {
 public:
};

GeneratedCodeInfo::GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                         bool is_message_owned)
  : ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
  SharedCtor(arena, is_message_owned);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo)
}
GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from)
  : ::PROTOBUF_NAMESPACE_ID::Message() {
  GeneratedCodeInfo* const _this = this; (void)_this;
  new (&_impl_) Impl_{
      decltype(_impl_.annotation_){from._impl_.annotation_}
    , /*decltype(_impl_._cached_size_)*/{}};

  _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo)
}

inline void GeneratedCodeInfo::SharedCtor(
    ::_pb::Arena* arena, bool is_message_owned) {
  (void)arena;
  (void)is_message_owned;
  new (&_impl_) Impl_{
      decltype(_impl_.annotation_){arena}
    , /*decltype(_impl_._cached_size_)*/{}
  };
}

GeneratedCodeInfo::~GeneratedCodeInfo() {
  // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo)
  if (auto *arena = _internal_metadata_.DeleteReturnArena<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>()) {
  (void)arena;
    return;
  }
  SharedDtor();
}

inline void GeneratedCodeInfo::SharedDtor() {
  GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
  _impl_.annotation_.~RepeatedPtrField();
}

void GeneratedCodeInfo::SetCachedSize(int size) const {
  _impl_._cached_size_.Set(size);
}

void GeneratedCodeInfo::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo)
  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.annotation_.Clear();
  _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}

const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
  while (!ctx->Done(&ptr)) {
    uint32_t tag;
    ptr = ::_pbi::ReadTag(ptr, &tag);
    switch (tag >> 3) {
      // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
      case 1:
        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
          ptr -= 1;
          do {
            ptr += 1;
            ptr = ctx->ParseMessage(_internal_add_annotation(), ptr);
            CHK_(ptr);
            if (!ctx->DataAvailable(ptr)) break;
          } while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
        } else
          goto handle_unusual;
        continue;
      default:
        goto handle_unusual;
    }  // switch
  handle_unusual:
    if ((tag == 0) || ((tag & 7) == 4)) {
      CHK_(ptr);
      ctx->SetLastTag(tag);
      goto message_done;
    }
    ptr = UnknownFieldParse(
        tag,
        _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
        ptr, ctx);
    CHK_(ptr != nullptr);
  }  // while
message_done:
  return ptr;
failure:
  ptr = nullptr;
  goto message_done;
#undef CHK_
}

uint8_t* GeneratedCodeInfo::_InternalSerialize(
    uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo)
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  for (unsigned i = 0,
      n = static_cast<unsigned>(this->_internal_annotation_size()); i < n; i++) {
    const auto& repfield = this->_internal_annotation(i);
    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
        InternalWriteMessage(1, repfield, repfield.GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target = ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo)
  return target;
}

size_t GeneratedCodeInfo::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo)
  size_t total_size = 0;

  uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
  total_size += 1UL * this->_internal_annotation_size();
  for (const auto& msg : this->_impl_.annotation_) {
    total_size +=
      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg);
  }

  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

const ::PROTOBUF_NAMESPACE_ID::Message::ClassData GeneratedCodeInfo::_class_data_ = {
    ::PROTOBUF_NAMESPACE_ID::Message::CopyWithSourceCheck,
    GeneratedCodeInfo::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GeneratedCodeInfo::GetClassData() const { return &_class_data_; }


void GeneratedCodeInfo::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg) {
  auto* const _this = static_cast<GeneratedCodeInfo*>(&to_msg);
  auto& from = static_cast<const GeneratedCodeInfo&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
  GOOGLE_DCHECK_NE(&from, _this);
  uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_impl_.annotation_.MergeFrom(from._impl_.annotation_);
  _this->_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}

void GeneratedCodeInfo::CopyFrom(const GeneratedCodeInfo& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool GeneratedCodeInfo::IsInitialized() const {
  return true;
}

void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) {
  using std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.annotation_.InternalSwap(&other->_impl_.annotation_);
}

::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo::GetMetadata() const {
  return ::_pbi::AssignDescriptors(
      &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
      file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]);
}

// @@protoc_insertion_point(namespace_scope)
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileDescriptorSet >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::DescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::DescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::OneofDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MethodDescriptorProto >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FileOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FileOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FileOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MessageOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MessageOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MessageOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::FieldOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::FieldOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::FieldOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::OneofOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::OneofOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::OneofOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::EnumValueOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::EnumValueOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::EnumValueOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::ServiceOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::ServiceOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::ServiceOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::MethodOptions*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::MethodOptions >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::MethodOptions >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::UninterpretedOption*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::UninterpretedOption >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::SourceCodeInfo >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation >(arena);
}
template<> PROTOBUF_NOINLINE ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo*
Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo >(Arena* arena) {
  return Arena::CreateMessageInternal< ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo >(arena);
}
PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc>
