// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/api.proto

#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 "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 3021000
#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 3021009 < 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_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

PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// 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 ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable
    descriptor_table_google_2fprotobuf_2fapi_2eproto;
PROTOBUF_NAMESPACE_OPEN
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_;
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Api>(Arena*);
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Method>(Arena*);
template <>
PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::Mixin>(Arena*);
PROTOBUF_NAMESPACE_CLOSE

PROTOBUF_NAMESPACE_OPEN

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


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

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::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 (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Api* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Api* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Api>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Api& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Api& from) {
    Api::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::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, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Api* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Api";
  }
  protected:
  explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

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

  ::PROTOBUF_NAMESPACE_ID::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();
  ::PROTOBUF_NAMESPACE_ID::Method* mutable_methods(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >*
      mutable_methods();
  private:
  const ::PROTOBUF_NAMESPACE_ID::Method& _internal_methods(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Method* _internal_add_methods();
  public:
  const ::PROTOBUF_NAMESPACE_ID::Method& methods(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Method* add_methods();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >&
      methods() const;

  // repeated .google.protobuf.Option options = 3;
  int options_size() const;
  private:
  int _internal_options_size() const;
  public:
  void clear_options();
  ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
      mutable_options();
  private:
  const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
  public:
  const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Option* add_options();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
      options() const;

  // repeated .google.protobuf.Mixin mixins = 6;
  int mixins_size() const;
  private:
  int _internal_mixins_size() const;
  public:
  void clear_mixins();
  ::PROTOBUF_NAMESPACE_ID::Mixin* mutable_mixins(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >*
      mutable_mixins();
  private:
  const ::PROTOBUF_NAMESPACE_ID::Mixin& _internal_mixins(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Mixin* _internal_add_mixins();
  public:
  const ::PROTOBUF_NAMESPACE_ID::Mixin& mixins(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Mixin* add_mixins();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >&
      mixins() const;

  // string name = 1;
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  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 ArgT0 = const std::string&, typename... ArgT>
  void set_version(ArgT0&& arg0, ArgT... args);
  std::string* mutable_version();
  PROTOBUF_NODISCARD std::string* release_version();
  void set_allocated_version(std::string* version);
  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;
  private:
  bool _internal_has_source_context() const;
  public:
  void clear_source_context();
  const ::PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
  ::PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
  void set_allocated_source_context(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
  private:
  const ::PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const;
  ::PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context();
  public:
  void unsafe_arena_set_allocated_source_context(
      ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context);
  ::PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context();

  // .google.protobuf.Syntax syntax = 7;
  void clear_syntax();
  ::PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
  void set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value);
  private:
  ::PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const;
  void _internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.Api)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method > methods_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin > mixins_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_;
    ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context_;
    int syntax_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};// -------------------------------------------------------------------

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::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 (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Method* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Method* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Method>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Method& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Method& from) {
    Method::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::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, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Method* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Method";
  }
  protected:
  explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

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

  ::PROTOBUF_NAMESPACE_ID::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();
  ::PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
      mutable_options();
  private:
  const ::PROTOBUF_NAMESPACE_ID::Option& _internal_options(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Option* _internal_add_options();
  public:
  const ::PROTOBUF_NAMESPACE_ID::Option& options(int index) const;
  ::PROTOBUF_NAMESPACE_ID::Option* add_options();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
      options() const;

  // string name = 1;
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  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 ArgT0 = const std::string&, typename... ArgT>
  void set_request_type_url(ArgT0&& arg0, ArgT... args);
  std::string* mutable_request_type_url();
  PROTOBUF_NODISCARD std::string* release_request_type_url();
  void set_allocated_request_type_url(std::string* request_type_url);
  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 ArgT0 = const std::string&, typename... ArgT>
  void set_response_type_url(ArgT0&& arg0, ArgT... args);
  std::string* mutable_response_type_url();
  PROTOBUF_NODISCARD std::string* release_response_type_url();
  void set_allocated_response_type_url(std::string* response_type_url);
  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();
  ::PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
  void set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value);
  private:
  ::PROTOBUF_NAMESPACE_ID::Syntax _internal_syntax() const;
  void _internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.Method)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option > options_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr request_type_url_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr response_type_url_;
    bool request_streaming_;
    bool response_streaming_;
    int syntax_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
};// -------------------------------------------------------------------

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

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

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::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 (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Mixin* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

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

  Mixin* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Mixin>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Mixin& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Mixin& from) {
    Mixin::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::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, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::uint8_t* _InternalSerialize(
      ::uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Mixin* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() {
    return "google.protobuf.Mixin";
  }
  protected:
  explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

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

  ::PROTOBUF_NAMESPACE_ID::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 ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  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 ArgT0 = const std::string&, typename... ArgT>
  void set_root(ArgT0&& arg0, ArgT... args);
  std::string* mutable_root();
  PROTOBUF_NODISCARD std::string* release_root();
  void set_allocated_root(std::string* root);
  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;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  };
  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() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Api::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Api::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.name)
}
inline std::string* Api::mutable_name() {
  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 {
  return _impl_.name_.Get();
}
inline void Api::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Api::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Api::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
  return _impl_.name_.Release();
}
inline void Api::set_allocated_name(std::string* name) {
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#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 _impl_.methods_.size();
}
inline int Api::methods_size() const {
  return _internal_methods_size();
}
inline void Api::clear_methods() {
  _impl_.methods_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Method* Api::mutable_methods(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods)
  return _impl_.methods_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >*
Api::mutable_methods() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods)
  return &_impl_.methods_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::_internal_methods(int index) const {
  return _impl_.methods_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::Method& Api::methods(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.methods)
  return _internal_methods(index);
}
inline ::PROTOBUF_NAMESPACE_ID::Method* Api::_internal_add_methods() {
  return _impl_.methods_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Method* Api::add_methods() {
  ::PROTOBUF_NAMESPACE_ID::Method* _add = _internal_add_methods();
  // @@protoc_insertion_point(field_add:google.protobuf.Api.methods)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Method >&
Api::methods() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
  return _impl_.methods_;
}

// repeated .google.protobuf.Option options = 3;
inline int Api::_internal_options_size() const {
  return _impl_.options_.size();
}
inline int Api::options_size() const {
  return _internal_options_size();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Api::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options)
  return _impl_.options_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
Api::mutable_options() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options)
  return &_impl_.options_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::_internal_options(int index) const {
  return _impl_.options_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Api::options(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.options)
  return _internal_options(index);
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Api::_internal_add_options() {
  return _impl_.options_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Api::add_options() {
  ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
  // @@protoc_insertion_point(field_add:google.protobuf.Api.options)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
Api::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
  return _impl_.options_;
}

// string version = 4;
inline void Api::clear_version() {
  _impl_.version_.ClearToEmpty();
}
inline const std::string& Api::version() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.version)
  return _internal_version();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Api::set_version(ArgT0&& arg0, ArgT... args) {
 
 _impl_.version_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Api.version)
}
inline std::string* Api::mutable_version() {
  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 {
  return _impl_.version_.Get();
}
inline void Api::_internal_set_version(const std::string& value) {

  _impl_.version_.Set(value, GetArenaForAllocation());
}
inline std::string* Api::_internal_mutable_version() {

  return _impl_.version_.Mutable(GetArenaForAllocation());
}
inline std::string* Api::release_version() {
  // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
  return _impl_.version_.Release();
}
inline void Api::set_allocated_version(std::string* version) {
  _impl_.version_.SetAllocated(version, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.version_.IsDefault()) {
    _impl_.version_.Set("", GetArenaForAllocation());
  }
#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::_internal_has_source_context() const {
  return this != internal_default_instance() && _impl_.source_context_ != nullptr;
}
inline bool Api::has_source_context() const {
  return _internal_has_source_context();
}
inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const {
  const ::PROTOBUF_NAMESPACE_ID::SourceContext* p = _impl_.source_context_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::SourceContext&>(
      ::PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
  return _internal_source_context();
}
inline void Api::unsafe_arena_set_allocated_source_context(
    ::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_);
  }
  _impl_.source_context_ = source_context;
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Api.source_context)
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() {
  
  ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::unsafe_arena_release_source_context() {
  // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context)
  
  ::PROTOBUF_NAMESPACE_ID::SourceContext* temp = _impl_.source_context_;
  _impl_.source_context_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_context() {
  
  if (_impl_.source_context_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::SourceContext>(GetArenaForAllocation());
    _impl_.source_context_ = p;
  }
  return _impl_.source_context_;
}
inline ::PROTOBUF_NAMESPACE_ID::SourceContext* Api::mutable_source_context() {
  ::PROTOBUF_NAMESPACE_ID::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(::PROTOBUF_NAMESPACE_ID::SourceContext* source_context) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.source_context_);
  }
  if (source_context) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
                reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context));
    if (message_arena != submessage_arena) {
      source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, source_context, submessage_arena);
    }

  } else {

  }
  _impl_.source_context_ = source_context;
  // @@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 _impl_.mixins_.size();
}
inline int Api::mixins_size() const {
  return _internal_mixins_size();
}
inline void Api::clear_mixins() {
  _impl_.mixins_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::mutable_mixins(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
  return _impl_.mixins_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >*
Api::mutable_mixins() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
  return &_impl_.mixins_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::_internal_mixins(int index) const {
  return _impl_.mixins_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::Mixin& Api::mixins(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
  return _internal_mixins(index);
}
inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::_internal_add_mixins() {
  return _impl_.mixins_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Mixin* Api::add_mixins() {
  ::PROTOBUF_NAMESPACE_ID::Mixin* _add = _internal_add_mixins();
  // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Mixin >&
Api::mixins() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
  return _impl_.mixins_;
}

// .google.protobuf.Syntax syntax = 7;
inline void Api::clear_syntax() {
  _impl_.syntax_ = 0;
}
inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::_internal_syntax() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.syntax_);
}
inline ::PROTOBUF_NAMESPACE_ID::Syntax Api::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
  return _internal_syntax();
}
inline void Api::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
  
  _impl_.syntax_ = value;
}
inline void Api::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
  _internal_set_syntax(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
}

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

// Method

// string name = 1;
inline void Method::clear_name() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Method::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Method::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.name)
}
inline std::string* Method::mutable_name() {
  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 {
  return _impl_.name_.Get();
}
inline void Method::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Method::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Method::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
  return _impl_.name_.Release();
}
inline void Method::set_allocated_name(std::string* name) {
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#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() {
  _impl_.request_type_url_.ClearToEmpty();
}
inline const std::string& Method::request_type_url() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url)
  return _internal_request_type_url();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Method::set_request_type_url(ArgT0&& arg0, ArgT... args) {
 
 _impl_.request_type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url)
}
inline std::string* Method::mutable_request_type_url() {
  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 {
  return _impl_.request_type_url_.Get();
}
inline void Method::_internal_set_request_type_url(const std::string& value) {

  _impl_.request_type_url_.Set(value, GetArenaForAllocation());
}
inline std::string* Method::_internal_mutable_request_type_url() {

  return _impl_.request_type_url_.Mutable(GetArenaForAllocation());
}
inline std::string* Method::release_request_type_url() {
  // @@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* request_type_url) {
  _impl_.request_type_url_.SetAllocated(request_type_url, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.request_type_url_.IsDefault()) {
    _impl_.request_type_url_.Set("", GetArenaForAllocation());
  }
#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() {
  _impl_.request_streaming_ = false;
}
inline bool Method::_internal_request_streaming() const {
  return _impl_.request_streaming_;
}
inline bool Method::request_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming)
  return _internal_request_streaming();
}
inline void Method::_internal_set_request_streaming(bool value) {

  _impl_.request_streaming_ = value;
}
inline void Method::set_request_streaming(bool value) {
  _internal_set_request_streaming(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming)
}

// string response_type_url = 4;
inline void Method::clear_response_type_url() {
  _impl_.response_type_url_.ClearToEmpty();
}
inline const std::string& Method::response_type_url() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url)
  return _internal_response_type_url();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Method::set_response_type_url(ArgT0&& arg0, ArgT... args) {
 
 _impl_.response_type_url_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url)
}
inline std::string* Method::mutable_response_type_url() {
  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 {
  return _impl_.response_type_url_.Get();
}
inline void Method::_internal_set_response_type_url(const std::string& value) {

  _impl_.response_type_url_.Set(value, GetArenaForAllocation());
}
inline std::string* Method::_internal_mutable_response_type_url() {

  return _impl_.response_type_url_.Mutable(GetArenaForAllocation());
}
inline std::string* Method::release_response_type_url() {
  // @@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* response_type_url) {
  _impl_.response_type_url_.SetAllocated(response_type_url, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.response_type_url_.IsDefault()) {
    _impl_.response_type_url_.Set("", GetArenaForAllocation());
  }
#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() {
  _impl_.response_streaming_ = false;
}
inline bool Method::_internal_response_streaming() const {
  return _impl_.response_streaming_;
}
inline bool Method::response_streaming() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming)
  return _internal_response_streaming();
}
inline void Method::_internal_set_response_streaming(bool value) {

  _impl_.response_streaming_ = value;
}
inline void Method::set_response_streaming(bool value) {
  _internal_set_response_streaming(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming)
}

// repeated .google.protobuf.Option options = 6;
inline int Method::_internal_options_size() const {
  return _impl_.options_.size();
}
inline int Method::options_size() const {
  return _internal_options_size();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Method::mutable_options(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options)
  return _impl_.options_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >*
Method::mutable_options() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
  return &_impl_.options_;
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::_internal_options(int index) const {
  return _impl_.options_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::Option& Method::options(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.options)
  return _internal_options(index);
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Method::_internal_add_options() {
  return _impl_.options_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::Option* Method::add_options() {
  ::PROTOBUF_NAMESPACE_ID::Option* _add = _internal_add_options();
  // @@protoc_insertion_point(field_add:google.protobuf.Method.options)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::Option >&
Method::options() const {
  // @@protoc_insertion_point(field_list:google.protobuf.Method.options)
  return _impl_.options_;
}

// .google.protobuf.Syntax syntax = 7;
inline void Method::clear_syntax() {
  _impl_.syntax_ = 0;
}
inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::_internal_syntax() const {
  return static_cast< ::PROTOBUF_NAMESPACE_ID::Syntax >(_impl_.syntax_);
}
inline ::PROTOBUF_NAMESPACE_ID::Syntax Method::syntax() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
  return _internal_syntax();
}
inline void Method::_internal_set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
  
  _impl_.syntax_ = value;
}
inline void Method::set_syntax(::PROTOBUF_NAMESPACE_ID::Syntax value) {
  _internal_set_syntax(value);
  // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
}

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

// Mixin

// string name = 1;
inline void Mixin::clear_name() {
  _impl_.name_.ClearToEmpty();
}
inline const std::string& Mixin::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Mixin::set_name(ArgT0&& arg0, ArgT... args) {
 
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
}
inline std::string* Mixin::mutable_name() {
  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 {
  return _impl_.name_.Get();
}
inline void Mixin::_internal_set_name(const std::string& value) {

  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* Mixin::_internal_mutable_name() {

  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* Mixin::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
  return _impl_.name_.Release();
}
inline void Mixin::set_allocated_name(std::string* name) {
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
}

// string root = 2;
inline void Mixin::clear_root() {
  _impl_.root_.ClearToEmpty();
}
inline const std::string& Mixin::root() const {
  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
  return _internal_root();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Mixin::set_root(ArgT0&& arg0, ArgT... args) {
 
 _impl_.root_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
}
inline std::string* Mixin::mutable_root() {
  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 {
  return _impl_.root_.Get();
}
inline void Mixin::_internal_set_root(const std::string& value) {

  _impl_.root_.Set(value, GetArenaForAllocation());
}
inline std::string* Mixin::_internal_mutable_root() {

  return _impl_.root_.Mutable(GetArenaForAllocation());
}
inline std::string* Mixin::release_root() {
  // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
  return _impl_.root_.Release();
}
inline void Mixin::set_allocated_root(std::string* root) {
  _impl_.root_.SetAllocated(root, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.root_.IsDefault()) {
    _impl_.root_.Set("", GetArenaForAllocation());
  }
#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)
PROTOBUF_NAMESPACE_CLOSE


// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh
