// 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 *::google::protobuf::internal::MessageGlobalsBase::default_instance<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 *::google::protobuf::internal::MessageGlobalsBase::default_instance<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 *::google::protobuf::internal::MessageGlobalsBase::default_instance<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 : *::google::protobuf::internal::MessageGlobalsBase::default_instance<::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
