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

#include "google/protobuf/api.pb.h"

#include <algorithm>
#include <type_traits>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/generated_message_util.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)

// Must be included last.
#include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG
namespace _pb = ::google::protobuf;
namespace _pbi = ::google::protobuf::internal;
namespace _fl = ::google::protobuf::internal::field_layout;
namespace google {
namespace protobuf {

inline constexpr Mixin::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : name_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        root_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        _cached_size_{0} {}

template <typename>
PROTOBUF_CONSTEXPR Mixin::Mixin(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct MixinDefaultTypeInternal {
  PROTOBUF_CONSTEXPR MixinDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~MixinDefaultTypeInternal() {}
  union {
    Mixin _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MixinDefaultTypeInternal _Mixin_default_instance_;

inline constexpr Method::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : options_{},
        name_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        request_type_url_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        response_type_url_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        request_streaming_{false},
        response_streaming_{false},
        syntax_{static_cast< ::google::protobuf::Syntax >(0)},
        _cached_size_{0} {}

template <typename>
PROTOBUF_CONSTEXPR Method::Method(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct MethodDefaultTypeInternal {
  PROTOBUF_CONSTEXPR MethodDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~MethodDefaultTypeInternal() {}
  union {
    Method _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDefaultTypeInternal _Method_default_instance_;

inline constexpr Api::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : _cached_size_{0},
        methods_{},
        options_{},
        mixins_{},
        name_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        version_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        source_context_{nullptr},
        syntax_{static_cast< ::google::protobuf::Syntax >(0)} {}

template <typename>
PROTOBUF_CONSTEXPR Api::Api(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct ApiDefaultTypeInternal {
  PROTOBUF_CONSTEXPR ApiDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~ApiDefaultTypeInternal() {}
  union {
    Api _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ApiDefaultTypeInternal _Api_default_instance_;
}  // namespace protobuf
}  // namespace google
static constexpr const ::_pb::EnumDescriptor**
    file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
static constexpr const ::_pb::ServiceDescriptor**
    file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
const ::uint32_t
    TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
        protodesc_cold) = {
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_._has_bits_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _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(::google::protobuf::Api, _impl_.name_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.methods_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.options_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.version_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.source_context_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.mixins_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Api, _impl_.syntax_),
        ~0u,
        ~0u,
        ~0u,
        ~0u,
        0,
        ~0u,
        ~0u,
        ~0u,  // no _has_bits_
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _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(::google::protobuf::Method, _impl_.name_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.request_type_url_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.request_streaming_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.response_type_url_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.response_streaming_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.options_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Method, _impl_.syntax_),
        ~0u,  // no _has_bits_
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _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(::google::protobuf::Mixin, _impl_.name_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::Mixin, _impl_.root_),
};

static const ::_pbi::MigrationSchema
    schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
        {0, 15, -1, sizeof(::google::protobuf::Api)},
        {22, -1, -1, sizeof(::google::protobuf::Method)},
        {37, -1, -1, sizeof(::google::protobuf::Mixin)},
};
static const ::_pb::Message* const file_default_instances[] = {
    &::google::protobuf::_Api_default_instance_._instance,
    &::google::protobuf::_Method_default_instance_._instance,
    &::google::protobuf::_Mixin_default_instance_._instance,
};
const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
    protodesc_cold) = {
    "\n\031google/protobuf/api.proto\022\017google.prot"
    "obuf\032$google/protobuf/source_context.pro"
    "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
    "\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
    "rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
    ".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
    "rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
    "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
    "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
    "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
    "equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
    "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
    "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
    "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
    "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
    "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBv\n\023com.google.pr"
    "otobufB\010ApiProtoP\001Z,google.golang.org/pr"
    "otobuf/types/known/apipb\242\002\003GPB\252\002\036Google."
    "Protobuf.WellKnownTypesb\006proto3"
};
static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] =
    {
        &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto,
        &::descriptor_table_google_2fprotobuf_2ftype_2eproto,
};
static ::absl::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once;
PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = {
    false,
    false,
    751,
    descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto,
    "google/protobuf/api.proto",
    &descriptor_table_google_2fprotobuf_2fapi_2eproto_once,
    descriptor_table_google_2fprotobuf_2fapi_2eproto_deps,
    2,
    3,
    schemas,
    file_default_instances,
    TableStruct_google_2fprotobuf_2fapi_2eproto::offsets,
    file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto,
    file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto,
};
namespace google {
namespace protobuf {
// ===================================================================

class Api::_Internal {
 public:
  using HasBits =
      decltype(std::declval<Api>()._impl_._has_bits_);
  static constexpr ::int32_t kHasBitsOffset =
      8 * PROTOBUF_FIELD_OFFSET(Api, _impl_._has_bits_);
};

void Api::clear_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.options_.Clear();
}
void Api::clear_source_context() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.source_context_ != nullptr) _impl_.source_context_->Clear();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
Api::Api(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Api)
}
inline PROTOBUF_NDEBUG_INLINE Api::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::Api& from_msg)
      : _has_bits_{from._has_bits_},
        _cached_size_{0},
        methods_{visibility, arena, from.methods_},
        options_{visibility, arena, from.options_},
        mixins_{visibility, arena, from.mixins_},
        name_(arena, from.name_),
        version_(arena, from.version_) {}

Api::Api(
    ::google::protobuf::Arena* arena,
    const Api& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  Api* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
  ::uint32_t cached_has_bits = _impl_._has_bits_[0];
  _impl_.source_context_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>(
                              arena, *from._impl_.source_context_)
                        : nullptr;
  _impl_.syntax_ = from._impl_.syntax_;

  // @@protoc_insertion_point(copy_constructor:google.protobuf.Api)
}
inline PROTOBUF_NDEBUG_INLINE Api::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : _cached_size_{0},
        methods_{visibility, arena},
        options_{visibility, arena},
        mixins_{visibility, arena},
        name_(arena),
        version_(arena) {}

inline void Api::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  ::memset(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, source_context_),
           0,
           offsetof(Impl_, syntax_) -
               offsetof(Impl_, source_context_) +
               sizeof(Impl_::syntax_));
}
Api::~Api() {
  // @@protoc_insertion_point(destructor:google.protobuf.Api)
  SharedDtor(*this);
}
inline void Api::SharedDtor(MessageLite& self) {
  Api& this_ = static_cast<Api&>(self);
  this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  ABSL_DCHECK(this_.GetArena() == nullptr);
  this_._impl_.name_.Destroy();
  this_._impl_.version_.Destroy();
  delete this_._impl_.source_context_;
  this_._impl_.~Impl_();
}

inline void* Api::PlacementNew_(const void*, void* mem,
                                        ::google::protobuf::Arena* arena) {
  return ::new (mem) Api(arena);
}
constexpr auto Api::InternalNewImpl_() {
  constexpr auto arena_bits = ::google::protobuf::internal::EncodePlacementArenaOffsets({
      PROTOBUF_FIELD_OFFSET(Api, _impl_.methods_) +
          decltype(Api::_impl_.methods_)::
              InternalGetArenaOffset(
                  ::google::protobuf::Message::internal_visibility()),
      PROTOBUF_FIELD_OFFSET(Api, _impl_.options_) +
          decltype(Api::_impl_.options_)::
              InternalGetArenaOffset(
                  ::google::protobuf::Message::internal_visibility()),
      PROTOBUF_FIELD_OFFSET(Api, _impl_.mixins_) +
          decltype(Api::_impl_.mixins_)::
              InternalGetArenaOffset(
                  ::google::protobuf::Message::internal_visibility()),
  });
  if (arena_bits.has_value()) {
    return ::google::protobuf::internal::MessageCreator::CopyInit(
        sizeof(Api), alignof(Api), *arena_bits);
  } else {
    return ::google::protobuf::internal::MessageCreator(&Api::PlacementNew_,
                                 sizeof(Api),
                                 alignof(Api));
  }
}
PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::internal::ClassDataFull Api::_class_data_ = {
    ::google::protobuf::internal::ClassData{
        &_Api_default_instance_._instance,
        &_table_.header,
        nullptr,  // OnDemandRegisterArenaDtor
        nullptr,  // IsInitialized
        &Api::MergeImpl,
        ::google::protobuf::Message::GetNewImpl<Api>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)
        &Api::SharedDtor,
        ::google::protobuf::Message::GetClearImpl<Api>(), &Api::ByteSizeLong,
            &Api::_InternalSerialize,
#endif  // PROTOBUF_CUSTOM_VTABLE
        PROTOBUF_FIELD_OFFSET(Api, _impl_._cached_size_),
        false,
    },
    &Api::kDescriptorMethods,
    &descriptor_table_google_2fprotobuf_2fapi_2eproto,
    nullptr,  // tracker
};
const ::google::protobuf::internal::ClassData* Api::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<3, 7, 4, 39, 2> Api::_table_ = {
  {
    PROTOBUF_FIELD_OFFSET(Api, _impl_._has_bits_),
    0, // no _extensions_
    7, 56,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294967168,  // skipmap
    offsetof(decltype(_table_), field_entries),
    7,  // num_field_entries
    4,  // num_aux_entries
    offsetof(decltype(_table_), aux_entries),
    _class_data_.base(),
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::Api>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    {::_pbi::TcParser::MiniParse, {}},
    // string name = 1;
    {::_pbi::TcParser::FastUS1,
     {10, 63, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.name_)}},
    // repeated .google.protobuf.Method methods = 2;
    {::_pbi::TcParser::FastMtR1,
     {18, 63, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.methods_)}},
    // repeated .google.protobuf.Option options = 3;
    {::_pbi::TcParser::FastMtR1,
     {26, 63, 1, PROTOBUF_FIELD_OFFSET(Api, _impl_.options_)}},
    // string version = 4;
    {::_pbi::TcParser::FastUS1,
     {34, 63, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.version_)}},
    // .google.protobuf.SourceContext source_context = 5;
    {::_pbi::TcParser::FastMtS1,
     {42, 0, 2, PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_)}},
    // repeated .google.protobuf.Mixin mixins = 6;
    {::_pbi::TcParser::FastMtR1,
     {50, 63, 3, PROTOBUF_FIELD_OFFSET(Api, _impl_.mixins_)}},
    // .google.protobuf.Syntax syntax = 7;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Api, _impl_.syntax_), 63>(),
     {56, 63, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_)}},
  }}, {{
    65535, 65535
  }}, {{
    // string name = 1;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.name_), -1, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
    // repeated .google.protobuf.Method methods = 2;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.methods_), -1, 0,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
    // repeated .google.protobuf.Option options = 3;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.options_), -1, 1,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
    // string version = 4;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.version_), -1, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
    // .google.protobuf.SourceContext source_context = 5;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_), _Internal::kHasBitsOffset + 0, 2,
    (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)},
    // repeated .google.protobuf.Mixin mixins = 6;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.mixins_), -1, 3,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
    // .google.protobuf.Syntax syntax = 7;
    {PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_), -1, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kOpenEnum)},
  }}, {{
    {::_pbi::TcParser::GetTable<::google::protobuf::Method>()},
    {::_pbi::TcParser::GetTable<::google::protobuf::Option>()},
    {::_pbi::TcParser::GetTable<::google::protobuf::SourceContext>()},
    {::_pbi::TcParser::GetTable<::google::protobuf::Mixin>()},
  }}, {{
    "\23\4\0\0\7\0\0\0"
    "google.protobuf.Api"
    "name"
    "version"
  }},
};

PROTOBUF_NOINLINE void Api::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Api)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.methods_.Clear();
  _impl_.options_.Clear();
  _impl_.mixins_.Clear();
  _impl_.name_.ClearToEmpty();
  _impl_.version_.ClearToEmpty();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    ABSL_DCHECK(_impl_.source_context_ != nullptr);
    _impl_.source_context_->Clear();
  }
  _impl_.syntax_ = 0;
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

#if defined(PROTOBUF_CUSTOM_VTABLE)
        ::uint8_t* Api::_InternalSerialize(
            const MessageLite& base, ::uint8_t* target,
            ::google::protobuf::io::EpsCopyOutputStream* stream) {
          const Api& this_ = static_cast<const Api&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
        ::uint8_t* Api::_InternalSerialize(
            ::uint8_t* target,
            ::google::protobuf::io::EpsCopyOutputStream* stream) const {
          const Api& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
          // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
          ::uint32_t cached_has_bits = 0;
          (void)cached_has_bits;

          // string name = 1;
          if (!this_._internal_name().empty()) {
            const std::string& _s = this_._internal_name();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Api.name");
            target = stream->WriteStringMaybeAliased(1, _s, target);
          }

          // repeated .google.protobuf.Method methods = 2;
          for (unsigned i = 0, n = static_cast<unsigned>(
                                   this_._internal_methods_size());
               i < n; i++) {
            const auto& repfield = this_._internal_methods().Get(i);
            target =
                ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
                    2, repfield, repfield.GetCachedSize(),
                    target, stream);
          }

          // repeated .google.protobuf.Option options = 3;
          for (unsigned i = 0, n = static_cast<unsigned>(
                                   this_._internal_options_size());
               i < n; i++) {
            const auto& repfield = this_._internal_options().Get(i);
            target =
                ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
                    3, repfield, repfield.GetCachedSize(),
                    target, stream);
          }

          // string version = 4;
          if (!this_._internal_version().empty()) {
            const std::string& _s = this_._internal_version();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Api.version");
            target = stream->WriteStringMaybeAliased(4, _s, target);
          }

          cached_has_bits = this_._impl_._has_bits_[0];
          // .google.protobuf.SourceContext source_context = 5;
          if (cached_has_bits & 0x00000001u) {
            target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
                5, *this_._impl_.source_context_, this_._impl_.source_context_->GetCachedSize(), target,
                stream);
          }

          // repeated .google.protobuf.Mixin mixins = 6;
          for (unsigned i = 0, n = static_cast<unsigned>(
                                   this_._internal_mixins_size());
               i < n; i++) {
            const auto& repfield = this_._internal_mixins().Get(i);
            target =
                ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
                    6, repfield, repfield.GetCachedSize(),
                    target, stream);
          }

          // .google.protobuf.Syntax syntax = 7;
          if (this_._internal_syntax() != 0) {
            target = stream->EnsureSpace(target);
            target = ::_pbi::WireFormatLite::WriteEnumToArray(
                7, this_._internal_syntax(), target);
          }

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

#if defined(PROTOBUF_CUSTOM_VTABLE)
        ::size_t Api::ByteSizeLong(const MessageLite& base) {
          const Api& this_ = static_cast<const Api&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
        ::size_t Api::ByteSizeLong() const {
          const Api& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
          // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Api)
          ::size_t total_size = 0;

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

          ::_pbi::Prefetch5LinesFrom7Lines(&this_);
           {
            // repeated .google.protobuf.Method methods = 2;
            {
              total_size += 1UL * this_._internal_methods_size();
              for (const auto& msg : this_._internal_methods()) {
                total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
              }
            }
            // repeated .google.protobuf.Option options = 3;
            {
              total_size += 1UL * this_._internal_options_size();
              for (const auto& msg : this_._internal_options()) {
                total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
              }
            }
            // repeated .google.protobuf.Mixin mixins = 6;
            {
              total_size += 1UL * this_._internal_mixins_size();
              for (const auto& msg : this_._internal_mixins()) {
                total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
              }
            }
          }
           {
            // string name = 1;
            if (!this_._internal_name().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_name());
            }
            // string version = 4;
            if (!this_._internal_version().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_version());
            }
          }
           {
            // .google.protobuf.SourceContext source_context = 5;
            cached_has_bits = this_._impl_._has_bits_[0];
            if (cached_has_bits & 0x00000001u) {
              total_size += 1 +
                            ::google::protobuf::internal::WireFormatLite::MessageSize(*this_._impl_.source_context_);
            }
          }
           {
            // .google.protobuf.Syntax syntax = 7;
            if (this_._internal_syntax() != 0) {
              total_size += 1 +
                            ::_pbi::WireFormatLite::EnumSize(this_._internal_syntax());
            }
          }
          return this_.MaybeComputeUnknownFieldsSize(total_size,
                                                     &this_._impl_._cached_size_);
        }

void Api::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
  auto* const _this = static_cast<Api*>(&to_msg);
  auto& from = static_cast<const Api&>(from_msg);
  ::google::protobuf::Arena* arena = _this->GetArena();
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
  ABSL_DCHECK_NE(&from, _this);
  ::uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_internal_mutable_methods()->MergeFrom(
      from._internal_methods());
  _this->_internal_mutable_options()->MergeFrom(
      from._internal_options());
  _this->_internal_mutable_mixins()->MergeFrom(
      from._internal_mixins());
  if (!from._internal_name().empty()) {
    _this->_internal_set_name(from._internal_name());
  }
  if (!from._internal_version().empty()) {
    _this->_internal_set_version(from._internal_version());
  }
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    ABSL_DCHECK(from._impl_.source_context_ != nullptr);
    if (_this->_impl_.source_context_ == nullptr) {
      _this->_impl_.source_context_ =
          ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_);
    } else {
      _this->_impl_.source_context_->MergeFrom(*from._impl_.source_context_);
    }
  }
  if (from._internal_syntax() != 0) {
    _this->_impl_.syntax_ = from._impl_.syntax_;
  }
  _this->_impl_._has_bits_[0] |= cached_has_bits;
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

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


void Api::InternalSwap(Api* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.methods_.InternalSwap(&other->_impl_.methods_);
  _impl_.options_.InternalSwap(&other->_impl_.options_);
  _impl_.mixins_.InternalSwap(&other->_impl_.mixins_);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.version_, &other->_impl_.version_, arena);
  ::google::protobuf::internal::memswap<
      PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_)
      + sizeof(Api::_impl_.syntax_)
      - PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_)>(
          reinterpret_cast<char*>(&_impl_.source_context_),
          reinterpret_cast<char*>(&other->_impl_.source_context_));
}

::google::protobuf::Metadata Api::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// ===================================================================

class Method::_Internal {
 public:
};

void Method::clear_options() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.options_.Clear();
}
Method::Method(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Method)
}
inline PROTOBUF_NDEBUG_INLINE Method::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::Method& from_msg)
      : options_{visibility, arena, from.options_},
        name_(arena, from.name_),
        request_type_url_(arena, from.request_type_url_),
        response_type_url_(arena, from.response_type_url_),
        _cached_size_{0} {}

Method::Method(
    ::google::protobuf::Arena* arena,
    const Method& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  Method* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
  ::memcpy(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, request_streaming_),
           reinterpret_cast<const char *>(&from._impl_) +
               offsetof(Impl_, request_streaming_),
           offsetof(Impl_, syntax_) -
               offsetof(Impl_, request_streaming_) +
               sizeof(Impl_::syntax_));

  // @@protoc_insertion_point(copy_constructor:google.protobuf.Method)
}
inline PROTOBUF_NDEBUG_INLINE Method::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : options_{visibility, arena},
        name_(arena),
        request_type_url_(arena),
        response_type_url_(arena),
        _cached_size_{0} {}

inline void Method::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  ::memset(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, request_streaming_),
           0,
           offsetof(Impl_, syntax_) -
               offsetof(Impl_, request_streaming_) +
               sizeof(Impl_::syntax_));
}
Method::~Method() {
  // @@protoc_insertion_point(destructor:google.protobuf.Method)
  SharedDtor(*this);
}
inline void Method::SharedDtor(MessageLite& self) {
  Method& this_ = static_cast<Method&>(self);
  this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  ABSL_DCHECK(this_.GetArena() == nullptr);
  this_._impl_.name_.Destroy();
  this_._impl_.request_type_url_.Destroy();
  this_._impl_.response_type_url_.Destroy();
  this_._impl_.~Impl_();
}

inline void* Method::PlacementNew_(const void*, void* mem,
                                        ::google::protobuf::Arena* arena) {
  return ::new (mem) Method(arena);
}
constexpr auto Method::InternalNewImpl_() {
  constexpr auto arena_bits = ::google::protobuf::internal::EncodePlacementArenaOffsets({
      PROTOBUF_FIELD_OFFSET(Method, _impl_.options_) +
          decltype(Method::_impl_.options_)::
              InternalGetArenaOffset(
                  ::google::protobuf::Message::internal_visibility()),
  });
  if (arena_bits.has_value()) {
    return ::google::protobuf::internal::MessageCreator::CopyInit(
        sizeof(Method), alignof(Method), *arena_bits);
  } else {
    return ::google::protobuf::internal::MessageCreator(&Method::PlacementNew_,
                                 sizeof(Method),
                                 alignof(Method));
  }
}
PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::internal::ClassDataFull Method::_class_data_ = {
    ::google::protobuf::internal::ClassData{
        &_Method_default_instance_._instance,
        &_table_.header,
        nullptr,  // OnDemandRegisterArenaDtor
        nullptr,  // IsInitialized
        &Method::MergeImpl,
        ::google::protobuf::Message::GetNewImpl<Method>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)
        &Method::SharedDtor,
        ::google::protobuf::Message::GetClearImpl<Method>(), &Method::ByteSizeLong,
            &Method::_InternalSerialize,
#endif  // PROTOBUF_CUSTOM_VTABLE
        PROTOBUF_FIELD_OFFSET(Method, _impl_._cached_size_),
        false,
    },
    &Method::kDescriptorMethods,
    &descriptor_table_google_2fprotobuf_2fapi_2eproto,
    nullptr,  // tracker
};
const ::google::protobuf::internal::ClassData* Method::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<3, 7, 1, 68, 2> Method::_table_ = {
  {
    0,  // no _has_bits_
    0, // no _extensions_
    7, 56,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294967168,  // skipmap
    offsetof(decltype(_table_), field_entries),
    7,  // num_field_entries
    1,  // num_aux_entries
    offsetof(decltype(_table_), aux_entries),
    _class_data_.base(),
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::Method>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    {::_pbi::TcParser::MiniParse, {}},
    // string name = 1;
    {::_pbi::TcParser::FastUS1,
     {10, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.name_)}},
    // string request_type_url = 2;
    {::_pbi::TcParser::FastUS1,
     {18, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.request_type_url_)}},
    // bool request_streaming = 3;
    {::_pbi::TcParser::SingularVarintNoZag1<bool, offsetof(Method, _impl_.request_streaming_), 63>(),
     {24, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.request_streaming_)}},
    // string response_type_url = 4;
    {::_pbi::TcParser::FastUS1,
     {34, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.response_type_url_)}},
    // bool response_streaming = 5;
    {::_pbi::TcParser::SingularVarintNoZag1<bool, offsetof(Method, _impl_.response_streaming_), 63>(),
     {40, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.response_streaming_)}},
    // repeated .google.protobuf.Option options = 6;
    {::_pbi::TcParser::FastMtR1,
     {50, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.options_)}},
    // .google.protobuf.Syntax syntax = 7;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Method, _impl_.syntax_), 63>(),
     {56, 63, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_)}},
  }}, {{
    65535, 65535
  }}, {{
    // string name = 1;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.name_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
    // string request_type_url = 2;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.request_type_url_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
    // bool request_streaming = 3;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.request_streaming_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kBool)},
    // string response_type_url = 4;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.response_type_url_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
    // bool response_streaming = 5;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.response_streaming_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kBool)},
    // repeated .google.protobuf.Option options = 6;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.options_), 0, 0,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
    // .google.protobuf.Syntax syntax = 7;
    {PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kOpenEnum)},
  }}, {{
    {::_pbi::TcParser::GetTable<::google::protobuf::Option>()},
  }}, {{
    "\26\4\20\0\21\0\0\0"
    "google.protobuf.Method"
    "name"
    "request_type_url"
    "response_type_url"
  }},
};

PROTOBUF_NOINLINE void Method::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Method)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.options_.Clear();
  _impl_.name_.ClearToEmpty();
  _impl_.request_type_url_.ClearToEmpty();
  _impl_.response_type_url_.ClearToEmpty();
  ::memset(&_impl_.request_streaming_, 0, static_cast<::size_t>(
      reinterpret_cast<char*>(&_impl_.syntax_) -
      reinterpret_cast<char*>(&_impl_.request_streaming_)) + sizeof(_impl_.syntax_));
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

#if defined(PROTOBUF_CUSTOM_VTABLE)
        ::uint8_t* Method::_InternalSerialize(
            const MessageLite& base, ::uint8_t* target,
            ::google::protobuf::io::EpsCopyOutputStream* stream) {
          const Method& this_ = static_cast<const Method&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
        ::uint8_t* Method::_InternalSerialize(
            ::uint8_t* target,
            ::google::protobuf::io::EpsCopyOutputStream* stream) const {
          const Method& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
          // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
          ::uint32_t cached_has_bits = 0;
          (void)cached_has_bits;

          // string name = 1;
          if (!this_._internal_name().empty()) {
            const std::string& _s = this_._internal_name();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Method.name");
            target = stream->WriteStringMaybeAliased(1, _s, target);
          }

          // string request_type_url = 2;
          if (!this_._internal_request_type_url().empty()) {
            const std::string& _s = this_._internal_request_type_url();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Method.request_type_url");
            target = stream->WriteStringMaybeAliased(2, _s, target);
          }

          // bool request_streaming = 3;
          if (this_._internal_request_streaming() != 0) {
            target = stream->EnsureSpace(target);
            target = ::_pbi::WireFormatLite::WriteBoolToArray(
                3, this_._internal_request_streaming(), target);
          }

          // string response_type_url = 4;
          if (!this_._internal_response_type_url().empty()) {
            const std::string& _s = this_._internal_response_type_url();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Method.response_type_url");
            target = stream->WriteStringMaybeAliased(4, _s, target);
          }

          // bool response_streaming = 5;
          if (this_._internal_response_streaming() != 0) {
            target = stream->EnsureSpace(target);
            target = ::_pbi::WireFormatLite::WriteBoolToArray(
                5, this_._internal_response_streaming(), target);
          }

          // repeated .google.protobuf.Option options = 6;
          for (unsigned i = 0, n = static_cast<unsigned>(
                                   this_._internal_options_size());
               i < n; i++) {
            const auto& repfield = this_._internal_options().Get(i);
            target =
                ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
                    6, repfield, repfield.GetCachedSize(),
                    target, stream);
          }

          // .google.protobuf.Syntax syntax = 7;
          if (this_._internal_syntax() != 0) {
            target = stream->EnsureSpace(target);
            target = ::_pbi::WireFormatLite::WriteEnumToArray(
                7, this_._internal_syntax(), target);
          }

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

#if defined(PROTOBUF_CUSTOM_VTABLE)
        ::size_t Method::ByteSizeLong(const MessageLite& base) {
          const Method& this_ = static_cast<const Method&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
        ::size_t Method::ByteSizeLong() const {
          const Method& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
          // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Method)
          ::size_t total_size = 0;

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

          ::_pbi::Prefetch5LinesFrom7Lines(&this_);
           {
            // repeated .google.protobuf.Option options = 6;
            {
              total_size += 1UL * this_._internal_options_size();
              for (const auto& msg : this_._internal_options()) {
                total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
              }
            }
          }
           {
            // string name = 1;
            if (!this_._internal_name().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_name());
            }
            // string request_type_url = 2;
            if (!this_._internal_request_type_url().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_request_type_url());
            }
            // string response_type_url = 4;
            if (!this_._internal_response_type_url().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_response_type_url());
            }
            // bool request_streaming = 3;
            if (this_._internal_request_streaming() != 0) {
              total_size += 2;
            }
            // bool response_streaming = 5;
            if (this_._internal_response_streaming() != 0) {
              total_size += 2;
            }
            // .google.protobuf.Syntax syntax = 7;
            if (this_._internal_syntax() != 0) {
              total_size += 1 +
                            ::_pbi::WireFormatLite::EnumSize(this_._internal_syntax());
            }
          }
          return this_.MaybeComputeUnknownFieldsSize(total_size,
                                                     &this_._impl_._cached_size_);
        }

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

  _this->_internal_mutable_options()->MergeFrom(
      from._internal_options());
  if (!from._internal_name().empty()) {
    _this->_internal_set_name(from._internal_name());
  }
  if (!from._internal_request_type_url().empty()) {
    _this->_internal_set_request_type_url(from._internal_request_type_url());
  }
  if (!from._internal_response_type_url().empty()) {
    _this->_internal_set_response_type_url(from._internal_response_type_url());
  }
  if (from._internal_request_streaming() != 0) {
    _this->_impl_.request_streaming_ = from._impl_.request_streaming_;
  }
  if (from._internal_response_streaming() != 0) {
    _this->_impl_.response_streaming_ = from._impl_.response_streaming_;
  }
  if (from._internal_syntax() != 0) {
    _this->_impl_.syntax_ = from._impl_.syntax_;
  }
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

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


void Method::InternalSwap(Method* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  _impl_.options_.InternalSwap(&other->_impl_.options_);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.request_type_url_, &other->_impl_.request_type_url_, arena);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.response_type_url_, &other->_impl_.response_type_url_, arena);
  ::google::protobuf::internal::memswap<
      PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_)
      + sizeof(Method::_impl_.syntax_)
      - PROTOBUF_FIELD_OFFSET(Method, _impl_.request_streaming_)>(
          reinterpret_cast<char*>(&_impl_.request_streaming_),
          reinterpret_cast<char*>(&other->_impl_.request_streaming_));
}

::google::protobuf::Metadata Method::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// ===================================================================

class Mixin::_Internal {
 public:
};

Mixin::Mixin(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin)
}
inline PROTOBUF_NDEBUG_INLINE Mixin::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::Mixin& from_msg)
      : name_(arena, from.name_),
        root_(arena, from.root_),
        _cached_size_{0} {}

Mixin::Mixin(
    ::google::protobuf::Arena* arena,
    const Mixin& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  Mixin* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);

  // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
}
inline PROTOBUF_NDEBUG_INLINE Mixin::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : name_(arena),
        root_(arena),
        _cached_size_{0} {}

inline void Mixin::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
}
Mixin::~Mixin() {
  // @@protoc_insertion_point(destructor:google.protobuf.Mixin)
  SharedDtor(*this);
}
inline void Mixin::SharedDtor(MessageLite& self) {
  Mixin& this_ = static_cast<Mixin&>(self);
  this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  ABSL_DCHECK(this_.GetArena() == nullptr);
  this_._impl_.name_.Destroy();
  this_._impl_.root_.Destroy();
  this_._impl_.~Impl_();
}

inline void* Mixin::PlacementNew_(const void*, void* mem,
                                        ::google::protobuf::Arena* arena) {
  return ::new (mem) Mixin(arena);
}
constexpr auto Mixin::InternalNewImpl_() {
  return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Mixin),
                                            alignof(Mixin));
}
PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::internal::ClassDataFull Mixin::_class_data_ = {
    ::google::protobuf::internal::ClassData{
        &_Mixin_default_instance_._instance,
        &_table_.header,
        nullptr,  // OnDemandRegisterArenaDtor
        nullptr,  // IsInitialized
        &Mixin::MergeImpl,
        ::google::protobuf::Message::GetNewImpl<Mixin>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)
        &Mixin::SharedDtor,
        ::google::protobuf::Message::GetClearImpl<Mixin>(), &Mixin::ByteSizeLong,
            &Mixin::_InternalSerialize,
#endif  // PROTOBUF_CUSTOM_VTABLE
        PROTOBUF_FIELD_OFFSET(Mixin, _impl_._cached_size_),
        false,
    },
    &Mixin::kDescriptorMethods,
    &descriptor_table_google_2fprotobuf_2fapi_2eproto,
    nullptr,  // tracker
};
const ::google::protobuf::internal::ClassData* Mixin::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<1, 2, 0, 38, 2> Mixin::_table_ = {
  {
    0,  // no _has_bits_
    0, // no _extensions_
    2, 8,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294967292,  // skipmap
    offsetof(decltype(_table_), field_entries),
    2,  // num_field_entries
    0,  // num_aux_entries
    offsetof(decltype(_table_), field_names),  // no aux_entries
    _class_data_.base(),
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::Mixin>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    // string root = 2;
    {::_pbi::TcParser::FastUS1,
     {18, 63, 0, PROTOBUF_FIELD_OFFSET(Mixin, _impl_.root_)}},
    // string name = 1;
    {::_pbi::TcParser::FastUS1,
     {10, 63, 0, PROTOBUF_FIELD_OFFSET(Mixin, _impl_.name_)}},
  }}, {{
    65535, 65535
  }}, {{
    // string name = 1;
    {PROTOBUF_FIELD_OFFSET(Mixin, _impl_.name_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
    // string root = 2;
    {PROTOBUF_FIELD_OFFSET(Mixin, _impl_.root_), 0, 0,
    (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)},
  }},
  // no aux_entries
  {{
    "\25\4\4\0\0\0\0\0"
    "google.protobuf.Mixin"
    "name"
    "root"
  }},
};

PROTOBUF_NOINLINE void Mixin::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.name_.ClearToEmpty();
  _impl_.root_.ClearToEmpty();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

#if defined(PROTOBUF_CUSTOM_VTABLE)
        ::uint8_t* Mixin::_InternalSerialize(
            const MessageLite& base, ::uint8_t* target,
            ::google::protobuf::io::EpsCopyOutputStream* stream) {
          const Mixin& this_ = static_cast<const Mixin&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
        ::uint8_t* Mixin::_InternalSerialize(
            ::uint8_t* target,
            ::google::protobuf::io::EpsCopyOutputStream* stream) const {
          const Mixin& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
          // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
          ::uint32_t cached_has_bits = 0;
          (void)cached_has_bits;

          // string name = 1;
          if (!this_._internal_name().empty()) {
            const std::string& _s = this_._internal_name();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Mixin.name");
            target = stream->WriteStringMaybeAliased(1, _s, target);
          }

          // string root = 2;
          if (!this_._internal_root().empty()) {
            const std::string& _s = this_._internal_root();
            ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
                _s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "google.protobuf.Mixin.root");
            target = stream->WriteStringMaybeAliased(2, _s, target);
          }

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

#if defined(PROTOBUF_CUSTOM_VTABLE)
        ::size_t Mixin::ByteSizeLong(const MessageLite& base) {
          const Mixin& this_ = static_cast<const Mixin&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
        ::size_t Mixin::ByteSizeLong() const {
          const Mixin& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
          // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Mixin)
          ::size_t total_size = 0;

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

          ::_pbi::Prefetch5LinesFrom7Lines(&this_);
           {
            // string name = 1;
            if (!this_._internal_name().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_name());
            }
            // string root = 2;
            if (!this_._internal_root().empty()) {
              total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                              this_._internal_root());
            }
          }
          return this_.MaybeComputeUnknownFieldsSize(total_size,
                                                     &this_._impl_._cached_size_);
        }

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

  if (!from._internal_name().empty()) {
    _this->_internal_set_name(from._internal_name());
  }
  if (!from._internal_root().empty()) {
    _this->_internal_set_root(from._internal_root());
  }
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

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


void Mixin::InternalSwap(Mixin* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.root_, &other->_impl_.root_, arena);
}

::google::protobuf::Metadata Mixin::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// @@protoc_insertion_point(namespace_scope)
}  // namespace protobuf
}  // namespace google
namespace google {
namespace protobuf {
}  // namespace protobuf
}  // namespace google
// @@protoc_insertion_point(global_scope)
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type
    _static_init2_ PROTOBUF_UNUSED =
        (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto),
         ::std::false_type{});
#include "google/protobuf/port_undef.inc"
