// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/api.proto
// Protobuf C++ Version: 4.25.4-dev

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh

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

#include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 4025000
#error "This file was generated by a newer version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please update"
#error "your headers."
#endif  // PROTOBUF_VERSION

#if 4025004 < PROTOBUF_MIN_PROTOC_VERSION
#error "This file was generated by an older version of protoc which is"
#error "incompatible with your Protocol Buffer headers. Please"
#error "regenerate this file with a newer version of protoc."
#endif  // PROTOBUF_MIN_PROTOC_VERSION
#include "google/protobuf/port_undef.inc"
#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/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 {
class AnyMetadata;
}  // 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[];
};
PROTOBUF_EXPORT extern const ::google::protobuf::internal::DescriptorTable
    descriptor_table_google_2fprotobuf_2fapi_2eproto;
namespace google {
namespace protobuf {
class Api;
struct ApiDefaultTypeInternal;
PROTOBUF_EXPORT extern ApiDefaultTypeInternal _Api_default_instance_;
class Method;
struct MethodDefaultTypeInternal;
PROTOBUF_EXPORT extern MethodDefaultTypeInternal _Method_default_instance_;
class Mixin;
struct MixinDefaultTypeInternal;
PROTOBUF_EXPORT extern MixinDefaultTypeInternal _Mixin_default_instance_;
}  // namespace protobuf
}  // namespace google

namespace google {
namespace protobuf {

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


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

class PROTOBUF_EXPORT Mixin final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ {
 public:
  inline Mixin() : Mixin(nullptr) {}
  ~Mixin() override;
  template<typename = void>
  explicit PROTOBUF_CONSTEXPR Mixin(::google::protobuf::internal::ConstantInitialized);

  inline Mixin(const Mixin& from)
      : Mixin(nullptr, from) {}
  Mixin(Mixin&& from) noexcept
    : Mixin() {
    *this = ::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 (GetArena() == from.GetArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  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);
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields()
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
  }

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Mixin& default_instance() {
    return *internal_default_instance();
  }
  static inline const Mixin* internal_default_instance() {
    return reinterpret_cast<const Mixin*>(
               &_Mixin_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(Mixin& a, Mixin& b) {
    a.Swap(&b);
  }
  inline void Swap(Mixin* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr &&
        GetArena() == other->GetArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Mixin* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  Mixin* New(::google::protobuf::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<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::Message& to_msg, const ::google::protobuf::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  ::size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  ::google::protobuf::internal::CachedSize* AccessCachedSize() const final;
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(Mixin* other);

  private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Mixin";
  }
  protected:
  explicit Mixin(::google::protobuf::Arena* arena);
  Mixin(::google::protobuf::Arena* arena, const Mixin& from);
  public:

  static const ClassData _class_data_;
  const ::google::protobuf::Message::ClassData*GetClassData() const final;

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

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

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

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

  private:
  const std::string& _internal_root() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_root(
      const std::string& value);
  std::string* _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;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct PROTOBUF_EXPORT Impl_ {

        inline explicit constexpr Impl_(
            ::google::protobuf::internal::ConstantInitialized) noexcept;
        inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                              ::google::protobuf::Arena* arena);
        inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                              ::google::protobuf::Arena* arena, const Impl_& from);
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr root_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT Method final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ {
 public:
  inline Method() : Method(nullptr) {}
  ~Method() override;
  template<typename = void>
  explicit PROTOBUF_CONSTEXPR Method(::google::protobuf::internal::ConstantInitialized);

  inline Method(const Method& from)
      : Method(nullptr, from) {}
  Method(Method&& from) noexcept
    : Method() {
    *this = ::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 (GetArena() == from.GetArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  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);
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields()
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
  }

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Method& default_instance() {
    return *internal_default_instance();
  }
  static inline const Method* internal_default_instance() {
    return reinterpret_cast<const Method*>(
               &_Method_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(Method& a, Method& b) {
    a.Swap(&b);
  }
  inline void Swap(Method* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr &&
        GetArena() == other->GetArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Method* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  Method* New(::google::protobuf::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<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::Message& to_msg, const ::google::protobuf::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  ::size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  ::google::protobuf::internal::CachedSize* AccessCachedSize() const final;
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(Method* other);

  private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Method";
  }
  protected:
  explicit Method(::google::protobuf::Arena* arena);
  Method(::google::protobuf::Arena* arena, const Method& from);
  public:

  static const ClassData _class_data_;
  const ::google::protobuf::Message::ClassData*GetClassData() const final;

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

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

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

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

  public:
  // string request_type_url = 2;
  void clear_request_type_url() ;
  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* mutable_request_type_url();
  PROTOBUF_NODISCARD std::string* release_request_type_url();
  void set_allocated_request_type_url(std::string* value);

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

  public:
  // string response_type_url = 4;
  void clear_response_type_url() ;
  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* mutable_response_type_url();
  PROTOBUF_NODISCARD std::string* release_response_type_url();
  void set_allocated_response_type_url(std::string* value);

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

  public:
  // bool request_streaming = 3;
  void clear_request_streaming() ;
  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() ;
  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;
  void clear_syntax() ;
  ::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.Method)
 private:
  class _Internal;

  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 7, 1,
      68, 2>
      _table_;
  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct PROTOBUF_EXPORT Impl_ {

        inline explicit constexpr Impl_(
            ::google::protobuf::internal::ConstantInitialized) noexcept;
        inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                              ::google::protobuf::Arena* arena);
        inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                              ::google::protobuf::Arena* arena, const Impl_& from);
    ::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_;
    bool request_streaming_;
    bool response_streaming_;
    int syntax_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};// -------------------------------------------------------------------

class PROTOBUF_EXPORT Api final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ {
 public:
  inline Api() : Api(nullptr) {}
  ~Api() override;
  template<typename = void>
  explicit PROTOBUF_CONSTEXPR Api(::google::protobuf::internal::ConstantInitialized);

  inline Api(const Api& from)
      : Api(nullptr, from) {}
  Api(Api&& from) noexcept
    : Api() {
    *this = ::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 (GetArena() == from.GetArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  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);
  }
  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields()
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
  }

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Api& default_instance() {
    return *internal_default_instance();
  }
  static inline const Api* internal_default_instance() {
    return reinterpret_cast<const Api*>(
               &_Api_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(Api& a, Api& b) {
    a.Swap(&b);
  }
  inline void Swap(Api* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() != nullptr &&
        GetArena() == other->GetArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Api* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  Api* New(::google::protobuf::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<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::Message& to_msg, const ::google::protobuf::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  ::size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  ::google::protobuf::internal::CachedSize* AccessCachedSize() const final;
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(Api* other);

  private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Api";
  }
  protected:
  explicit Api(::google::protobuf::Arena* arena);
  Api(::google::protobuf::Arena* arena, const Api& from);
  public:

  static const ClassData _class_data_;
  const ::google::protobuf::Message::ClassData*GetClassData() const final;

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

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

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

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

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

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

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

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

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

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

  public:
  // .google.protobuf.Syntax syntax = 7;
  void clear_syntax() ;
  ::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, 7, 4,
      39, 2>
      _table_;
  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct PROTOBUF_EXPORT Impl_ {

        inline explicit constexpr Impl_(
            ::google::protobuf::internal::ConstantInitialized) noexcept;
        inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                              ::google::protobuf::Arena* arena);
        inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                              ::google::protobuf::Arena* arena, const Impl_& from);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::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::SourceContext* source_context_;
    int syntax_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};

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




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


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

// Api

// string name = 1;
inline void Api::clear_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.name_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Api::set_name(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.name)
}
inline std::string* Api::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.name_.Get();
}
inline void Api::_internal_set_name(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* Api::_internal_mutable_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* Api::release_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
  return _impl_.name_.Release();
}
inline void Api::set_allocated_name(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@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() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.methods_.Clear();
}
inline ::google::protobuf::Method* 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>* Api::mutable_methods()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods)
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  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* Api::add_methods() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ::google::protobuf::Method* _add = _internal_mutable_methods()->Add();
  // @@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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.methods_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>*
Api::_internal_mutable_methods() {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  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* 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>* Api::mutable_options()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options)
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  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* Api::add_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ::google::protobuf::Option* _add = _internal_mutable_options()->Add();
  // @@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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.options_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>*
Api::_internal_mutable_options() {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return &_impl_.options_;
}

// string version = 4;
inline void Api::clear_version() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.version_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Api::set_version(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.version_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.version)
}
inline std::string* Api::mutable_version() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.version_.Get();
}
inline void Api::_internal_set_version(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.version_.Set(value, GetArena());
}
inline std::string* Api::_internal_mutable_version() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.version_.Mutable( GetArena());
}
inline std::string* Api::release_version() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
  return _impl_.version_.Release();
}
inline void Api::set_allocated_version(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.version_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.version_.IsDefault()) {
          _impl_.version_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@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 = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.source_context_ != nullptr);
  return value;
}
inline const ::google::protobuf::SourceContext& Api::_internal_source_context() const {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  const ::google::protobuf::SourceContext* p = _impl_.source_context_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::SourceContext&>(::google::protobuf::_SourceContext_default_instance_);
}
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* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.source_context_);
  }
  _impl_.source_context_ = reinterpret_cast<::google::protobuf::SourceContext*>(value);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Api.source_context)
}
inline ::google::protobuf::SourceContext* Api::release_source_context() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::SourceContext* released = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::SourceContext* Api::unsafe_arena_release_source_context() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context)

  _impl_._has_bits_[0] &= ~0x00000001u;
  ::google::protobuf::SourceContext* temp = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
  return temp;
}
inline ::google::protobuf::SourceContext* Api::_internal_mutable_source_context() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_._has_bits_[0] |= 0x00000001u;
  if (_impl_.source_context_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::SourceContext>(GetArena());
    _impl_.source_context_ = reinterpret_cast<::google::protobuf::SourceContext*>(p);
  }
  return _impl_.source_context_;
}
inline ::google::protobuf::SourceContext* Api::mutable_source_context() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::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* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  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::MessageLite*>(value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }

  _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() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.mixins_.Clear();
}
inline ::google::protobuf::Mixin* 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>* Api::mutable_mixins()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  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* Api::add_mixins() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ::google::protobuf::Mixin* _add = _internal_mutable_mixins()->Add();
  // @@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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.mixins_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>*
Api::_internal_mutable_mixins() {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return &_impl_.mixins_;
}

// .google.protobuf.Syntax syntax = 7;
inline void Api::clear_syntax() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.syntax_ = 0;
}
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);
  // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
}
inline ::google::protobuf::Syntax Api::_internal_syntax() const {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return static_cast<::google::protobuf::Syntax>(_impl_.syntax_);
}
inline void Api::_internal_set_syntax(::google::protobuf::Syntax value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.syntax_ = value;
}

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

// Method

// string name = 1;
inline void Method::clear_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.name_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Method::set_name(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.name)
}
inline std::string* Method::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.name_.Get();
}
inline void Method::_internal_set_name(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* Method::_internal_mutable_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* Method::release_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
  return _impl_.name_.Release();
}
inline void Method::set_allocated_name(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name)
}

// string request_type_url = 2;
inline void Method::clear_request_type_url() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.request_type_url_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Method::set_request_type_url(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _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* Method::mutable_request_type_url() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.request_type_url_.Get();
}
inline void Method::_internal_set_request_type_url(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.request_type_url_.Set(value, GetArena());
}
inline std::string* Method::_internal_mutable_request_type_url() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.request_type_url_.Mutable( GetArena());
}
inline std::string* Method::release_request_type_url() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url)
  return _impl_.request_type_url_.Release();
}
inline void Method::set_allocated_request_type_url(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.request_type_url_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.request_type_url_.IsDefault()) {
          _impl_.request_type_url_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url)
}

// bool request_streaming = 3;
inline void Method::clear_request_streaming() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.request_streaming_ = false;
}
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);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming)
}
inline bool Method::_internal_request_streaming() const {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.request_streaming_;
}
inline void Method::_internal_set_request_streaming(bool value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.request_streaming_ = value;
}

// string response_type_url = 4;
inline void Method::clear_response_type_url() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.response_type_url_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Method::set_response_type_url(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _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* Method::mutable_response_type_url() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.response_type_url_.Get();
}
inline void Method::_internal_set_response_type_url(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.response_type_url_.Set(value, GetArena());
}
inline std::string* Method::_internal_mutable_response_type_url() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.response_type_url_.Mutable( GetArena());
}
inline std::string* Method::release_response_type_url() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url)
  return _impl_.response_type_url_.Release();
}
inline void Method::set_allocated_response_type_url(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.response_type_url_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.response_type_url_.IsDefault()) {
          _impl_.response_type_url_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url)
}

// bool response_streaming = 5;
inline void Method::clear_response_streaming() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.response_streaming_ = false;
}
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);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming)
}
inline bool Method::_internal_response_streaming() const {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.response_streaming_;
}
inline void Method::_internal_set_response_streaming(bool value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _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* 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>* Method::mutable_options()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  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* Method::add_options() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ::google::protobuf::Option* _add = _internal_mutable_options()->Add();
  // @@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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.options_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>*
Method::_internal_mutable_options() {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return &_impl_.options_;
}

// .google.protobuf.Syntax syntax = 7;
inline void Method::clear_syntax() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.syntax_ = 0;
}
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);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
}
inline ::google::protobuf::Syntax Method::_internal_syntax() const {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return static_cast<::google::protobuf::Syntax>(_impl_.syntax_);
}
inline void Method::_internal_set_syntax(::google::protobuf::Syntax value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.syntax_ = value;
}

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

// Mixin

// string name = 1;
inline void Mixin::clear_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.name_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Mixin::set_name(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
}
inline std::string* Mixin::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.name_.Get();
}
inline void Mixin::_internal_set_name(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* Mixin::_internal_mutable_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* Mixin::release_name() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
  return _impl_.name_.Release();
}
inline void Mixin::set_allocated_name(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
}

// string root = 2;
inline void Mixin::clear_root() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.root_.ClearToEmpty();
}
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_>
inline PROTOBUF_ALWAYS_INLINE void Mixin::set_root(Arg_&& arg,
                                                     Args_... args) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.root_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
}
inline std::string* Mixin::mutable_root() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race);
  return _impl_.root_.Get();
}
inline void Mixin::_internal_set_root(const std::string& value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  _impl_.root_.Set(value, GetArena());
}
inline std::string* Mixin::_internal_mutable_root() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  ;
  return _impl_.root_.Mutable( GetArena());
}
inline std::string* Mixin::release_root() {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
  return _impl_.root_.Release();
}
inline void Mixin::set_allocated_root(std::string* value) {
  PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race);
  _impl_.root_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.root_.IsDefault()) {
          _impl_.root_.Set("", GetArena());
        }
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@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"

#endif  // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh
