// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/api.proto
// Protobuf C++ Version: 5.28.0-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/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)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void Api::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.name_.Destroy();
  _impl_.version_.Destroy();
  delete _impl_.source_context_;
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    Api::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            nullptr,  // IsInitialized
            &Api::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<Api>(),
            ::google::protobuf::Message::GetNewImpl<Api>(),
            ::google::protobuf::Message::GetClearImpl<Api>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<Api>(),
                ::google::protobuf::Message::GetSerializeImpl<Api>(),
#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::MessageLite::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),
    &_Api_default_instance_._instance,
    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>();
}

::uint8_t* Api::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@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 = _impl_._has_bits_[0];
  // .google.protobuf.SourceContext source_context = 5;
  if (cached_has_bits & 0x00000001u) {
    target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
        5, *_impl_.source_context_, _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(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _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;
}

::size_t Api::ByteSizeLong() const {
  // @@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(
      reinterpret_cast<const void*>(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 = _impl_._has_bits_[0];
    if (cached_has_bits & 0x00000001u) {
      total_size +=
          1 + ::google::protobuf::internal::WireFormatLite::MessageSize(*_impl_.source_context_);
    }
  }
   {
    // .google.protobuf.Syntax syntax = 7;
    if (this->_internal_syntax() != 0) {
      total_size += 1 +
                    ::_pbi::WireFormatLite::EnumSize(this->_internal_syntax());
    }
  }
  return MaybeComputeUnknownFieldsSize(total_size, &_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)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void Method::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.name_.Destroy();
  _impl_.request_type_url_.Destroy();
  _impl_.response_type_url_.Destroy();
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    Method::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            nullptr,  // IsInitialized
            &Method::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<Method>(),
            ::google::protobuf::Message::GetNewImpl<Method>(),
            ::google::protobuf::Message::GetClearImpl<Method>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<Method>(),
                ::google::protobuf::Message::GetSerializeImpl<Method>(),
#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::MessageLite::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),
    &_Method_default_instance_._instance,
    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>();
}

::uint8_t* Method::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@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(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _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;
}

::size_t Method::ByteSizeLong() const {
  // @@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(
      reinterpret_cast<const void*>(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 MaybeComputeUnknownFieldsSize(total_size, &_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)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void Mixin::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.name_.Destroy();
  _impl_.root_.Destroy();
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    Mixin::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            nullptr,  // IsInitialized
            &Mixin::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<Mixin>(),
            ::google::protobuf::Message::GetNewImpl<Mixin>(),
            ::google::protobuf::Message::GetClearImpl<Mixin>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<Mixin>(),
                ::google::protobuf::Message::GetSerializeImpl<Mixin>(),
#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::MessageLite::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
    &_Mixin_default_instance_._instance,
    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>();
}

::uint8_t* Mixin::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@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(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _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;
}

::size_t Mixin::ByteSizeLong() const {
  // @@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(
      reinterpret_cast<const void*>(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 MaybeComputeUnknownFieldsSize(total_size, &_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"
