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

#ifndef google_2fprotobuf_2fapi_2eproto_2epb_2eh
#define google_2fprotobuf_2fapi_2eproto_2epb_2eh

#include <limits>
#include <string>
#include <type_traits>
#include <utility>

// clang-format off
#include "google/protobuf/runtime_version.h"
#if PROTOBUF_VERSION != 7035000
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
#endif
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_tctable_decl.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/metadata_lite.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/message.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/repeated_field.h"  // IWYU pragma: export
#include "google/protobuf/extension_set.h"  // IWYU pragma: export
#include "google/protobuf/unknown_field_set.h"
#include "google/protobuf/source_context.pb.h"
#include "google/protobuf/type.pb.h"
// @@protoc_insertion_point(includes)

// Must be included last.
#include "google/protobuf/port_def.inc"

#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto PROTOBUF_EXPORT

namespace google {
namespace protobuf {
namespace internal {
template <typename T>
::absl::string_view GetAnyMessageName();
}  // namespace internal
}  // namespace protobuf
}  // namespace google

// Internal implementation detail -- do not use these members.
struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fapi_2eproto {
  static const ::uint32_t offsets[];
};
extern "C" {
PROTOBUF_EXPORT extern const ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto;
}  // extern "C"
namespace google {
namespace protobuf {
class Api;
struct ApiGlobalsTypeInternal;
PROTOBUF_EXPORT extern ApiGlobalsTypeInternal _Api_globals_;
PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Api_class_data_;
class Method;
struct MethodGlobalsTypeInternal;
PROTOBUF_EXPORT extern MethodGlobalsTypeInternal _Method_globals_;
PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Method_class_data_;
class Mixin;
struct MixinGlobalsTypeInternal;
PROTOBUF_EXPORT extern MixinGlobalsTypeInternal _Mixin_globals_;
PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Mixin_class_data_;
}  // namespace protobuf
}  // namespace google

namespace google {
namespace protobuf {

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


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

class PROTOBUF_EXPORT  PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ {
 public:
  inline Mixin() : Mixin(nullptr) {}
  ~Mixin() PROTOBUF_FINAL;

#if defined(PROTOBUF_CUSTOM_VTABLE)
  void operator delete(Mixin* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
    SharedDtor(*msg);
    ::google::protobuf::internal::SizedDelete(msg, sizeof(Mixin));
  }
#endif

  template <typename = void>
  explicit constexpr Mixin(::google::protobuf::internal::ConstantInitialized);

  inline Mixin(const Mixin& from) : Mixin(nullptr, from) {}
  inline Mixin(Mixin&& from) noexcept
      : Mixin(nullptr, ::std::move(from)) {}
  inline Mixin& operator=(const Mixin& from) {
    CopyFrom(from);
    return *this;
  }
  inline Mixin& operator=(Mixin&& from) noexcept {
    if (this == &from) return *this;
    if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
    return GetDescriptor();
  }
  [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
  GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  [[nodiscard]] static const Mixin& default_instance() {
    return *reinterpret_cast<const Mixin*>(&_Mixin_globals_);
  }
  static constexpr int kIndexInFileMessages = 2;
  friend void swap(Mixin& a, Mixin& b) { a.Swap(&b); }
  inline void Swap(Mixin* PROTOBUF_NONNULL other) {
    if (other == this) return;
    if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Mixin* PROTOBUF_NONNULL other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  [[nodiscard]] Mixin* PROTOBUF_NONNULL
  New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
    return ::google::protobuf::Message::DefaultConstruct<Mixin>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const Mixin& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const Mixin& from) { Mixin::MergeImpl(*this, from); }

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

  public:
  [[nodiscard]] bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  #if defined(PROTOBUF_CUSTOM_VTABLE)
  private:
  [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
  [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);

  public:
  [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
  [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
    return _InternalSerialize(*this, target, stream);
  }
  #else   // PROTOBUF_CUSTOM_VTABLE
  [[nodiscard]] ::size_t ByteSizeLong() const final;
  [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
  #endif  // PROTOBUF_CUSTOM_VTABLE
  [[nodiscard]] int GetCachedSize() const {
    return _impl_._cached_size_.Get();
  }

  private:
  void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  static void SharedDtor(MessageLite& self);
  void InternalSwap(Mixin* PROTOBUF_NONNULL other);
 private:
  template <typename T>
  friend ::absl::string_view(::google::protobuf::internal::GetAnyMessageName)();
  static ::absl::string_view FullMessageName() { return "google.protobuf.Mixin"; }

  explicit Mixin(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  Mixin(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Mixin& from);
  Mixin(
      ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, Mixin&& from) noexcept
      : Mixin(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
  static void* PROTOBUF_NONNULL PlacementNew_(
      const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
      ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  static constexpr auto InternalNewImpl_();

 public:
  static constexpr auto InternalGenerateClassData_();

  [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kNameFieldNumber = 1,
    kRootFieldNumber = 2,
  };
  // string name = 1;
  void clear_name() ;
  [[nodiscard]] const ::std::string& name() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_name();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_name();
  void set_allocated_name(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_name() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_name(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_name();

  public:
  // string root = 2;
  void clear_root() ;
  [[nodiscard]] const ::std::string& root() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_root(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_root();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_root();
  void set_allocated_root(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_root() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_root(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_root();

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

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

PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Mixin_class_data_;
// -------------------------------------------------------------------

class PROTOBUF_EXPORT  PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ {
 public:
  inline Method() : Method(nullptr) {}
  ~Method() PROTOBUF_FINAL;

#if defined(PROTOBUF_CUSTOM_VTABLE)
  void operator delete(Method* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
    SharedDtor(*msg);
    ::google::protobuf::internal::SizedDelete(msg, sizeof(Method));
  }
#endif

  template <typename = void>
  explicit constexpr Method(::google::protobuf::internal::ConstantInitialized);

  inline Method(const Method& from) : Method(nullptr, from) {}
  inline Method(Method&& from) noexcept
      : Method(nullptr, ::std::move(from)) {}
  inline Method& operator=(const Method& from) {
    CopyFrom(from);
    return *this;
  }
  inline Method& operator=(Method&& from) noexcept {
    if (this == &from) return *this;
    if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
    return GetDescriptor();
  }
  [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
  GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  [[nodiscard]] static const Method& default_instance() {
    return *reinterpret_cast<const Method*>(&_Method_globals_);
  }
  static constexpr int kIndexInFileMessages = 1;
  friend void swap(Method& a, Method& b) { a.Swap(&b); }
  inline void Swap(Method* PROTOBUF_NONNULL other) {
    if (other == this) return;
    if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Method* PROTOBUF_NONNULL other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  [[nodiscard]] Method* PROTOBUF_NONNULL
  New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
    return ::google::protobuf::Message::DefaultConstruct<Method>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const Method& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const Method& from) { Method::MergeImpl(*this, from); }

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

  public:
  [[nodiscard]] bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  #if defined(PROTOBUF_CUSTOM_VTABLE)
  private:
  [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
  [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);

  public:
  [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
  [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
    return _InternalSerialize(*this, target, stream);
  }
  #else   // PROTOBUF_CUSTOM_VTABLE
  [[nodiscard]] ::size_t ByteSizeLong() const final;
  [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
  #endif  // PROTOBUF_CUSTOM_VTABLE
  [[nodiscard]] int GetCachedSize() const {
    return _impl_._cached_size_.Get();
  }

  private:
  void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  static void SharedDtor(MessageLite& self);
  void InternalSwap(Method* PROTOBUF_NONNULL other);
 private:
  template <typename T>
  friend ::absl::string_view(::google::protobuf::internal::GetAnyMessageName)();
  static ::absl::string_view FullMessageName() { return "google.protobuf.Method"; }

  explicit Method(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  Method(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Method& from);
  Method(
      ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, Method&& from) noexcept
      : Method(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
  static void* PROTOBUF_NONNULL PlacementNew_(
      const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
      ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  static constexpr auto InternalNewImpl_();

 public:
  static constexpr auto InternalGenerateClassData_();

  [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kOptionsFieldNumber = 6,
    kNameFieldNumber = 1,
    kRequestTypeUrlFieldNumber = 2,
    kResponseTypeUrlFieldNumber = 4,
    kEditionFieldNumber = 8,
    kRequestStreamingFieldNumber = 3,
    kResponseStreamingFieldNumber = 5,
    kSyntaxFieldNumber = 7,
  };
  // repeated .google.protobuf.Option options = 6;
  [[nodiscard]] int options_size()
      const;
  private:
  int _internal_options_size() const;

  public:
  void clear_options() ;
  [[nodiscard]] ::google::protobuf::Option* PROTOBUF_NONNULL mutable_options(int index);
  [[nodiscard]] ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL
  mutable_options();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& _internal_options() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL _internal_mutable_options();
  public:
  [[nodiscard]] const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* PROTOBUF_NONNULL add_options();
  [[nodiscard]] const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& options()
      const;
  // string name = 1;
  void clear_name() ;
  [[nodiscard]] const ::std::string& name() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_name();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_name();
  void set_allocated_name(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_name() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_name(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_name();

  public:
  // string request_type_url = 2;
  void clear_request_type_url() ;
  [[nodiscard]] const ::std::string& request_type_url() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_request_type_url(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_request_type_url();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_request_type_url();
  void set_allocated_request_type_url(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_request_type_url() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_request_type_url(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_request_type_url();

  public:
  // string response_type_url = 4;
  void clear_response_type_url() ;
  [[nodiscard]] const ::std::string& response_type_url() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_response_type_url(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_response_type_url();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_response_type_url();
  void set_allocated_response_type_url(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_response_type_url() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_response_type_url(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_response_type_url();

  public:
  // string edition = 8 [deprecated = true];
  [[deprecated]]  void clear_edition() ;
  [[nodiscard]] [[deprecated]] const ::std::string& edition() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  [[deprecated]] void set_edition(Arg_&& arg, Args_... args);
  [[deprecated]] ::std::string* PROTOBUF_NONNULL mutable_edition();
  [[deprecated]] [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_edition();
  [[deprecated]] void set_allocated_edition(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_edition() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_edition(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_edition();

  public:
  // bool request_streaming = 3;
  void clear_request_streaming() ;
  [[nodiscard]] bool request_streaming() const;
  void set_request_streaming(bool value);

  private:
  bool _internal_request_streaming() const;
  void _internal_set_request_streaming(bool value);

  public:
  // bool response_streaming = 5;
  void clear_response_streaming() ;
  [[nodiscard]] bool response_streaming() const;
  void set_response_streaming(bool value);

  private:
  bool _internal_response_streaming() const;
  void _internal_set_response_streaming(bool value);

  public:
  // .google.protobuf.Syntax syntax = 7 [deprecated = true];
  [[deprecated]]  void clear_syntax() ;
  [[nodiscard]] [[deprecated]] ::google::protobuf::Syntax syntax() const;
  [[deprecated]] void set_syntax(::google::protobuf::Syntax value);

  private:
  ::google::protobuf::Syntax _internal_syntax() const;
  void _internal_set_syntax(::google::protobuf::Syntax value);

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

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  friend ::google::protobuf::internal::PrivateAccess;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
                                    ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(
        ::google::protobuf::internal::InternalVisibility visibility,
        ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
    inline explicit Impl_(
        ::google::protobuf::internal::InternalVisibility visibility,
        ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
        const Method& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr request_type_url_;
    ::google::protobuf::internal::ArenaStringPtr response_type_url_;
    ::google::protobuf::internal::ArenaStringPtr edition_;
    bool request_streaming_;
    bool response_streaming_;
    int syntax_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};

PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Method_class_data_;
// -------------------------------------------------------------------

class PROTOBUF_EXPORT  PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ {
 public:
  inline Api() : Api(nullptr) {}
  ~Api() PROTOBUF_FINAL;

#if defined(PROTOBUF_CUSTOM_VTABLE)
  void operator delete(Api* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
    SharedDtor(*msg);
    ::google::protobuf::internal::SizedDelete(msg, sizeof(Api));
  }
#endif

  template <typename = void>
  explicit constexpr Api(::google::protobuf::internal::ConstantInitialized);

  inline Api(const Api& from) : Api(nullptr, from) {}
  inline Api(Api&& from) noexcept
      : Api(nullptr, ::std::move(from)) {}
  inline Api& operator=(const Api& from) {
    CopyFrom(from);
    return *this;
  }
  inline Api& operator=(Api&& from) noexcept {
    if (this == &from) return *this;
    if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
    return GetDescriptor();
  }
  [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
  GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  [[nodiscard]] static const Api& default_instance() {
    return *reinterpret_cast<const Api*>(&_Api_globals_);
  }
  static constexpr int kIndexInFileMessages = 0;
  friend void swap(Api& a, Api& b) { a.Swap(&b); }
  inline void Swap(Api* PROTOBUF_NONNULL other) {
    if (other == this) return;
    if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Api* PROTOBUF_NONNULL other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  [[nodiscard]] Api* PROTOBUF_NONNULL
  New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
    return ::google::protobuf::Message::DefaultConstruct<Api>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const Api& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const Api& from) { Api::MergeImpl(*this, from); }

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

  public:
  [[nodiscard]] bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  #if defined(PROTOBUF_CUSTOM_VTABLE)
  private:
  [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
  [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);

  public:
  [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
  [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
    return _InternalSerialize(*this, target, stream);
  }
  #else   // PROTOBUF_CUSTOM_VTABLE
  [[nodiscard]] ::size_t ByteSizeLong() const final;
  [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
      ::uint8_t* PROTOBUF_NONNULL target,
      ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
  #endif  // PROTOBUF_CUSTOM_VTABLE
  [[nodiscard]] int GetCachedSize() const {
    return _impl_._cached_size_.Get();
  }

  private:
  void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  static void SharedDtor(MessageLite& self);
  void InternalSwap(Api* PROTOBUF_NONNULL other);
 private:
  template <typename T>
  friend ::absl::string_view(::google::protobuf::internal::GetAnyMessageName)();
  static ::absl::string_view FullMessageName() { return "google.protobuf.Api"; }

  explicit Api(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  Api(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Api& from);
  Api(
      ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, Api&& from) noexcept
      : Api(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
  static void* PROTOBUF_NONNULL PlacementNew_(
      const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
      ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
  static constexpr auto InternalNewImpl_();

 public:
  static constexpr auto InternalGenerateClassData_();

  [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kMethodsFieldNumber = 2,
    kOptionsFieldNumber = 3,
    kMixinsFieldNumber = 6,
    kNameFieldNumber = 1,
    kVersionFieldNumber = 4,
    kEditionFieldNumber = 8,
    kSourceContextFieldNumber = 5,
    kSyntaxFieldNumber = 7,
  };
  // repeated .google.protobuf.Method methods = 2;
  [[nodiscard]] int methods_size()
      const;
  private:
  int _internal_methods_size() const;

  public:
  void clear_methods() ;
  [[nodiscard]] ::google::protobuf::Method* PROTOBUF_NONNULL mutable_methods(int index);
  [[nodiscard]] ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* PROTOBUF_NONNULL
  mutable_methods();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& _internal_methods() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* PROTOBUF_NONNULL _internal_mutable_methods();
  public:
  [[nodiscard]] const ::google::protobuf::Method& methods(int index) const;
  ::google::protobuf::Method* PROTOBUF_NONNULL add_methods();
  [[nodiscard]] const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& methods()
      const;
  // repeated .google.protobuf.Option options = 3;
  [[nodiscard]] int options_size()
      const;
  private:
  int _internal_options_size() const;

  public:
  void clear_options() ;
  [[nodiscard]] ::google::protobuf::Option* PROTOBUF_NONNULL mutable_options(int index);
  [[nodiscard]] ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL
  mutable_options();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& _internal_options() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL _internal_mutable_options();
  public:
  [[nodiscard]] const ::google::protobuf::Option& options(int index) const;
  ::google::protobuf::Option* PROTOBUF_NONNULL add_options();
  [[nodiscard]] const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& options()
      const;
  // repeated .google.protobuf.Mixin mixins = 6;
  [[nodiscard]] int mixins_size()
      const;
  private:
  int _internal_mixins_size() const;

  public:
  void clear_mixins() ;
  [[nodiscard]] ::google::protobuf::Mixin* PROTOBUF_NONNULL mutable_mixins(int index);
  [[nodiscard]] ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* PROTOBUF_NONNULL
  mutable_mixins();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& _internal_mixins() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* PROTOBUF_NONNULL _internal_mutable_mixins();
  public:
  [[nodiscard]] const ::google::protobuf::Mixin& mixins(int index) const;
  ::google::protobuf::Mixin* PROTOBUF_NONNULL add_mixins();
  [[nodiscard]] const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& mixins()
      const;
  // string name = 1;
  void clear_name() ;
  [[nodiscard]] const ::std::string& name() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_name();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_name();
  void set_allocated_name(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_name() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_name(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_name();

  public:
  // string version = 4;
  void clear_version() ;
  [[nodiscard]] const ::std::string& version() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_version(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_version();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_version();
  void set_allocated_version(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_version() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_version(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_version();

  public:
  // string edition = 8;
  void clear_edition() ;
  [[nodiscard]] const ::std::string& edition() const;
  template <typename Arg_ = const ::std::string&, typename... Args_>
  void set_edition(Arg_&& arg, Args_... args);
  ::std::string* PROTOBUF_NONNULL mutable_edition();
  [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_edition();
  void set_allocated_edition(::std::string* PROTOBUF_NULLABLE value);

  private:
  const ::std::string& _internal_edition() const;
  PROTOBUF_ALWAYS_INLINE void _internal_set_edition(const ::std::string& value);
  ::std::string* PROTOBUF_NONNULL _internal_mutable_edition();

  public:
  // .google.protobuf.SourceContext source_context = 5;
  [[nodiscard]] bool has_source_context()
      const;
  void clear_source_context() ;
  [[nodiscard]] const ::google::protobuf::SourceContext& source_context() const;
  [[nodiscard]] ::google::protobuf::SourceContext* PROTOBUF_NULLABLE release_source_context();
  ::google::protobuf::SourceContext* PROTOBUF_NONNULL mutable_source_context();
  void set_allocated_source_context(::google::protobuf::SourceContext* PROTOBUF_NULLABLE value);
  void unsafe_arena_set_allocated_source_context(::google::protobuf::SourceContext* PROTOBUF_NULLABLE value);
  ::google::protobuf::SourceContext* PROTOBUF_NULLABLE unsafe_arena_release_source_context();

  private:
  const ::google::protobuf::SourceContext& _internal_source_context() const;
  ::google::protobuf::SourceContext* PROTOBUF_NONNULL _internal_mutable_source_context();

  public:
  // .google.protobuf.Syntax syntax = 7;
  void clear_syntax() ;
  [[nodiscard]] ::google::protobuf::Syntax syntax() const;
  void set_syntax(::google::protobuf::Syntax value);

  private:
  ::google::protobuf::Syntax _internal_syntax() const;
  void _internal_set_syntax(::google::protobuf::Syntax value);

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

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  friend ::google::protobuf::internal::PrivateAccess;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
                                    ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(
        ::google::protobuf::internal::InternalVisibility visibility,
        ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
    inline explicit Impl_(
        ::google::protobuf::internal::InternalVisibility visibility,
        ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
        const Api& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method > methods_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin > mixins_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr version_;
    ::google::protobuf::internal::ArenaStringPtr edition_;
    ::google::protobuf::SourceContext* PROTOBUF_NULLABLE source_context_;
    int syntax_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};

PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Api_class_data_;

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




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


#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// -------------------------------------------------------------------

// Api

// string name = 1;
inline void Api::clear_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000008U);
}
inline const ::std::string& Api::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.name)
  return _internal_name();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Api::set_name(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000008U);
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.name)
}
inline ::std::string* PROTOBUF_NONNULL Api::mutable_name()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000008U);
  ::std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.name)
  return _s;
}
inline const ::std::string& Api::_internal_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void Api::_internal_set_name(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Api::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.name_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Api::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000008U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
  auto* released = _impl_.name_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.name_.Set("", GetArena());
  }
  return released;
}
inline void Api::set_allocated_name(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000008U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
  }
  _impl_.name_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name)
}

// repeated .google.protobuf.Method methods = 2;
inline int Api::_internal_methods_size() const {
  return _internal_methods().size();
}
inline int Api::methods_size() const {
  return _internal_methods_size();
}
inline void Api::clear_methods() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.methods_.Clear();
  ClearHasBitForRepeated(_impl_._has_bits_[0],
                  0x00000001U);
}
inline ::google::protobuf::Method* PROTOBUF_NONNULL Api::mutable_methods(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods)
  return _internal_mutable_methods()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* PROTOBUF_NONNULL Api::mutable_methods()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000001U);
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_methods();
}
inline const ::google::protobuf::Method& Api::methods(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.methods)
  return _internal_methods().Get(index);
}
inline ::google::protobuf::Method* PROTOBUF_NONNULL Api::add_methods()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::Method* _add =
      _internal_mutable_methods()->InternalAddWithArena(
          ::google::protobuf::MessageLite::internal_visibility(), GetArena());
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000001U);
  // @@protoc_insertion_point(field_add:google.protobuf.Api.methods)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& Api::methods() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
  return _internal_methods();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>&
Api::_internal_methods() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.methods_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* PROTOBUF_NONNULL
Api::_internal_mutable_methods() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.methods_;
}

// repeated .google.protobuf.Option options = 3;
inline int Api::_internal_options_size() const {
  return _internal_options().size();
}
inline int Api::options_size() const {
  return _internal_options_size();
}
inline ::google::protobuf::Option* PROTOBUF_NONNULL Api::mutable_options(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options)
  return _internal_mutable_options()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL Api::mutable_options()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000002U);
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_options();
}
inline const ::google::protobuf::Option& Api::options(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.options)
  return _internal_options().Get(index);
}
inline ::google::protobuf::Option* PROTOBUF_NONNULL Api::add_options()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::Option* _add =
      _internal_mutable_options()->InternalAddWithArena(
          ::google::protobuf::MessageLite::internal_visibility(), GetArena());
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000002U);
  // @@protoc_insertion_point(field_add:google.protobuf.Api.options)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& Api::options() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
  return _internal_options();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>&
Api::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.options_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL
Api::_internal_mutable_options() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.options_;
}

// string version = 4;
inline void Api::clear_version() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.version_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000010U);
}
inline const ::std::string& Api::version() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.version)
  return _internal_version();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Api::set_version(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000010U);
  _impl_.version_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.version)
}
inline ::std::string* PROTOBUF_NONNULL Api::mutable_version()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000010U);
  ::std::string* _s = _internal_mutable_version();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.version)
  return _s;
}
inline const ::std::string& Api::_internal_version() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.version_.Get();
}
inline void Api::_internal_set_version(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.version_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Api::_internal_mutable_version() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.version_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Api::release_version() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000010U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000010U);
  auto* released = _impl_.version_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.version_.Set("", GetArena());
  }
  return released;
}
inline void Api::set_allocated_version(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000010U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000010U);
  }
  _impl_.version_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.version_.IsDefault()) {
    _impl_.version_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version)
}

// .google.protobuf.SourceContext source_context = 5;
inline bool Api::has_source_context() const {
  bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000040U);
  PROTOBUF_ASSUME(!value || _impl_.source_context_ != nullptr);
  return value;
}
inline const ::google::protobuf::SourceContext& Api::_internal_source_context() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::SourceContext* p = _impl_.source_context_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::SourceContext&>(::google::protobuf::_SourceContext_globals_);
}
inline const ::google::protobuf::SourceContext& Api::source_context() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
  return _internal_source_context();
}
inline void Api::unsafe_arena_set_allocated_source_context(
    ::google::protobuf::SourceContext* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.source_context_);
  }
  _impl_.source_context_ = reinterpret_cast<::google::protobuf::SourceContext*>(value);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000040U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000040U);
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Api.source_context)
}
inline ::google::protobuf::SourceContext* PROTOBUF_NULLABLE Api::release_source_context() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  ClearHasBit(_impl_._has_bits_[0], 0x00000040U);
  ::google::protobuf::SourceContext* released = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
  if (::google::protobuf::internal::DebugHardenForceCopyInRelease()) {
    auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
    if (GetArena() == nullptr) {
      delete old;
    }
  } else {
    if (GetArena() != nullptr) {
      released = ::google::protobuf::internal::DuplicateIfNonNull(released);
    }
  }
  return released;
}
inline ::google::protobuf::SourceContext* PROTOBUF_NULLABLE Api::unsafe_arena_release_source_context() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context)

  ClearHasBit(_impl_._has_bits_[0], 0x00000040U);
  ::google::protobuf::SourceContext* temp = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
  return temp;
}
inline ::google::protobuf::SourceContext* PROTOBUF_NONNULL Api::_internal_mutable_source_context() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.source_context_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::SourceContext>(GetArena());
    _impl_.source_context_ = reinterpret_cast<::google::protobuf::SourceContext*>(p);
  }
  return _impl_.source_context_;
}
inline ::google::protobuf::SourceContext* PROTOBUF_NONNULL Api::mutable_source_context()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000040U);
  ::google::protobuf::SourceContext* _msg = _internal_mutable_source_context();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context)
  return _msg;
}
inline void Api::set_allocated_source_context(::google::protobuf::SourceContext* PROTOBUF_NULLABLE value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.source_context_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::Message*>(value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    SetHasBit(_impl_._has_bits_[0], 0x00000040U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000040U);
  }

  _impl_.source_context_ = reinterpret_cast<::google::protobuf::SourceContext*>(value);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
}

// repeated .google.protobuf.Mixin mixins = 6;
inline int Api::_internal_mixins_size() const {
  return _internal_mixins().size();
}
inline int Api::mixins_size() const {
  return _internal_mixins_size();
}
inline void Api::clear_mixins() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.mixins_.Clear();
  ClearHasBitForRepeated(_impl_._has_bits_[0],
                  0x00000004U);
}
inline ::google::protobuf::Mixin* PROTOBUF_NONNULL Api::mutable_mixins(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
  return _internal_mutable_mixins()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* PROTOBUF_NONNULL Api::mutable_mixins()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000004U);
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_mixins();
}
inline const ::google::protobuf::Mixin& Api::mixins(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
  return _internal_mixins().Get(index);
}
inline ::google::protobuf::Mixin* PROTOBUF_NONNULL Api::add_mixins()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::Mixin* _add =
      _internal_mutable_mixins()->InternalAddWithArena(
          ::google::protobuf::MessageLite::internal_visibility(), GetArena());
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000004U);
  // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& Api::mixins() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
  return _internal_mixins();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>&
Api::_internal_mixins() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.mixins_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* PROTOBUF_NONNULL
Api::_internal_mutable_mixins() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.mixins_;
}

// .google.protobuf.Syntax syntax = 7;
inline void Api::clear_syntax() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.syntax_ = 0;
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000080U);
}
inline ::google::protobuf::Syntax Api::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
  return _internal_syntax();
}
inline void Api::set_syntax(::google::protobuf::Syntax value) {
  _internal_set_syntax(value);
  SetHasBit(_impl_._has_bits_[0], 0x00000080U);
  // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
}
inline ::google::protobuf::Syntax Api::_internal_syntax() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Syntax>(_impl_.syntax_);
}
inline void Api::_internal_set_syntax(::google::protobuf::Syntax value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.syntax_ = value;
}

// string edition = 8;
inline void Api::clear_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000020U);
}
inline const ::std::string& Api::edition() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.edition)
  return _internal_edition();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Api::set_edition(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000020U);
  _impl_.edition_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.edition)
}
inline ::std::string* PROTOBUF_NONNULL Api::mutable_edition()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000020U);
  ::std::string* _s = _internal_mutable_edition();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.edition)
  return _s;
}
inline const ::std::string& Api::_internal_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.edition_.Get();
}
inline void Api::_internal_set_edition(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Api::_internal_mutable_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.edition_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Api::release_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.edition)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000020U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000020U);
  auto* released = _impl_.edition_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.edition_.Set("", GetArena());
  }
  return released;
}
inline void Api::set_allocated_edition(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000020U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000020U);
  }
  _impl_.edition_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.edition_.IsDefault()) {
    _impl_.edition_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.edition)
}

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

// Method

// string name = 1;
inline void Method::clear_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000002U);
}
inline const ::std::string& Method::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.name)
  return _internal_name();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Method::set_name(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000002U);
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.name)
}
inline ::std::string* PROTOBUF_NONNULL Method::mutable_name()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000002U);
  ::std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Method.name)
  return _s;
}
inline const ::std::string& Method::_internal_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void Method::_internal_set_name(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Method::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.name_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Method::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000002U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
  auto* released = _impl_.name_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.name_.Set("", GetArena());
  }
  return released;
}
inline void Method::set_allocated_name(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000002U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
  }
  _impl_.name_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name)
}

// string request_type_url = 2;
inline void Method::clear_request_type_url() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.request_type_url_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000004U);
}
inline const ::std::string& Method::request_type_url() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url)
  return _internal_request_type_url();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Method::set_request_type_url(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000004U);
  _impl_.request_type_url_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url)
}
inline ::std::string* PROTOBUF_NONNULL Method::mutable_request_type_url()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000004U);
  ::std::string* _s = _internal_mutable_request_type_url();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url)
  return _s;
}
inline const ::std::string& Method::_internal_request_type_url() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.request_type_url_.Get();
}
inline void Method::_internal_set_request_type_url(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.request_type_url_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Method::_internal_mutable_request_type_url() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.request_type_url_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Method::release_request_type_url() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000004U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000004U);
  auto* released = _impl_.request_type_url_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.request_type_url_.Set("", GetArena());
  }
  return released;
}
inline void Method::set_allocated_request_type_url(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000004U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000004U);
  }
  _impl_.request_type_url_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.request_type_url_.IsDefault()) {
    _impl_.request_type_url_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url)
}

// bool request_streaming = 3;
inline void Method::clear_request_streaming() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.request_streaming_ = false;
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000020U);
}
inline bool Method::request_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming)
  return _internal_request_streaming();
}
inline void Method::set_request_streaming(bool value) {
  _internal_set_request_streaming(value);
  SetHasBit(_impl_._has_bits_[0], 0x00000020U);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming)
}
inline bool Method::_internal_request_streaming() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.request_streaming_;
}
inline void Method::_internal_set_request_streaming(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.request_streaming_ = value;
}

// string response_type_url = 4;
inline void Method::clear_response_type_url() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.response_type_url_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000008U);
}
inline const ::std::string& Method::response_type_url() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url)
  return _internal_response_type_url();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Method::set_response_type_url(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000008U);
  _impl_.response_type_url_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url)
}
inline ::std::string* PROTOBUF_NONNULL Method::mutable_response_type_url()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000008U);
  ::std::string* _s = _internal_mutable_response_type_url();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url)
  return _s;
}
inline const ::std::string& Method::_internal_response_type_url() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.response_type_url_.Get();
}
inline void Method::_internal_set_response_type_url(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.response_type_url_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Method::_internal_mutable_response_type_url() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.response_type_url_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Method::release_response_type_url() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000008U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
  auto* released = _impl_.response_type_url_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.response_type_url_.Set("", GetArena());
  }
  return released;
}
inline void Method::set_allocated_response_type_url(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000008U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000008U);
  }
  _impl_.response_type_url_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.response_type_url_.IsDefault()) {
    _impl_.response_type_url_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url)
}

// bool response_streaming = 5;
inline void Method::clear_response_streaming() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.response_streaming_ = false;
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000040U);
}
inline bool Method::response_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming)
  return _internal_response_streaming();
}
inline void Method::set_response_streaming(bool value) {
  _internal_set_response_streaming(value);
  SetHasBit(_impl_._has_bits_[0], 0x00000040U);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming)
}
inline bool Method::_internal_response_streaming() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.response_streaming_;
}
inline void Method::_internal_set_response_streaming(bool value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.response_streaming_ = value;
}

// repeated .google.protobuf.Option options = 6;
inline int Method::_internal_options_size() const {
  return _internal_options().size();
}
inline int Method::options_size() const {
  return _internal_options_size();
}
inline ::google::protobuf::Option* PROTOBUF_NONNULL Method::mutable_options(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options)
  return _internal_mutable_options()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL Method::mutable_options()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000001U);
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_options();
}
inline const ::google::protobuf::Option& Method::options(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.options)
  return _internal_options().Get(index);
}
inline ::google::protobuf::Option* PROTOBUF_NONNULL Method::add_options()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::Option* _add =
      _internal_mutable_options()->InternalAddWithArena(
          ::google::protobuf::MessageLite::internal_visibility(), GetArena());
  SetHasBitForRepeated(_impl_._has_bits_[0], 0x00000001U);
  // @@protoc_insertion_point(field_add:google.protobuf.Method.options)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& Method::options() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.Method.options)
  return _internal_options();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>&
Method::_internal_options() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.options_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* PROTOBUF_NONNULL
Method::_internal_mutable_options() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.options_;
}

// .google.protobuf.Syntax syntax = 7 [deprecated = true];
inline void Method::clear_syntax() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.syntax_ = 0;
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000080U);
}
inline ::google::protobuf::Syntax Method::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
  return _internal_syntax();
}
inline void Method::set_syntax(::google::protobuf::Syntax value) {
  _internal_set_syntax(value);
  SetHasBit(_impl_._has_bits_[0], 0x00000080U);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
}
inline ::google::protobuf::Syntax Method::_internal_syntax() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return static_cast<::google::protobuf::Syntax>(_impl_.syntax_);
}
inline void Method::_internal_set_syntax(::google::protobuf::Syntax value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.syntax_ = value;
}

// string edition = 8 [deprecated = true];
inline void Method::clear_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000010U);
}
inline const ::std::string& Method::edition() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.edition)
  return _internal_edition();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Method::set_edition(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000010U);
  _impl_.edition_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.edition)
}
inline ::std::string* PROTOBUF_NONNULL Method::mutable_edition()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000010U);
  ::std::string* _s = _internal_mutable_edition();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Method.edition)
  return _s;
}
inline const ::std::string& Method::_internal_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.edition_.Get();
}
inline void Method::_internal_set_edition(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.edition_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Method::_internal_mutable_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.edition_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Method::release_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.edition)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000010U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000010U);
  auto* released = _impl_.edition_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.edition_.Set("", GetArena());
  }
  return released;
}
inline void Method::set_allocated_edition(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000010U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000010U);
  }
  _impl_.edition_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.edition_.IsDefault()) {
    _impl_.edition_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.edition)
}

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

// Mixin

// string name = 1;
inline void Mixin::clear_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000001U);
}
inline const ::std::string& Mixin::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
  return _internal_name();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Mixin::set_name(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000001U);
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
}
inline ::std::string* PROTOBUF_NONNULL Mixin::mutable_name()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000001U);
  ::std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
  return _s;
}
inline const ::std::string& Mixin::_internal_name() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void Mixin::_internal_set_name(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Mixin::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.name_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Mixin::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000001U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
  auto* released = _impl_.name_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.name_.Set("", GetArena());
  }
  return released;
}
inline void Mixin::set_allocated_name(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000001U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
  }
  _impl_.name_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
}

// string root = 2;
inline void Mixin::clear_root() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.root_.ClearToEmpty();
  ClearHasBit(_impl_._has_bits_[0],
                  0x00000002U);
}
inline const ::std::string& Mixin::root() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
  return _internal_root();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Mixin::set_root(Arg_&& arg, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  SetHasBit(_impl_._has_bits_[0], 0x00000002U);
  _impl_.root_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
}
inline ::std::string* PROTOBUF_NONNULL Mixin::mutable_root()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  SetHasBit(_impl_._has_bits_[0], 0x00000002U);
  ::std::string* _s = _internal_mutable_root();
  // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
  return _s;
}
inline const ::std::string& Mixin::_internal_root() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.root_.Get();
}
inline void Mixin::_internal_set_root(const ::std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.root_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Mixin::_internal_mutable_root() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _impl_.root_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Mixin::release_root() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
  if (!CheckHasBit(_impl_._has_bits_[0], 0x00000002U)) {
    return nullptr;
  }
  ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
  auto* released = _impl_.root_.Release();
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {
    _impl_.root_.Set("", GetArena());
  }
  return released;
}
inline void Mixin::set_allocated_root(::std::string* PROTOBUF_NULLABLE value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    SetHasBit(_impl_._has_bits_[0], 0x00000002U);
  } else {
    ClearHasBit(_impl_._has_bits_[0], 0x00000002U);
  }
  _impl_.root_.SetAllocated(value, GetArena());
  if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.root_.IsDefault()) {
    _impl_.root_.Set("", GetArena());
  }
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
}

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif  // __GNUC__

// @@protoc_insertion_point(namespace_scope)
}  // namespace protobuf
}  // namespace google


// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"
// clang-format on

#endif  // google_2fprotobuf_2fapi_2eproto_2epb_2eh
