// WARNING: This file is machine generated by fidlgen.

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.anonymous/cpp/markers.h>
#include <fidl/test.anonymous/cpp/wire_types.h>
#include <lib/fidl/cpp/wire/wire_messaging.h>

#ifdef __Fuchsia__

#include <lib/fidl/cpp/wire/client.h>
#include <lib/fidl/cpp/wire/connect_service.h>
#include <lib/fidl/cpp/wire/server.h>
#include <lib/fidl/cpp/wire/service_handler.h>
#include <lib/fidl/cpp/wire/sync_call.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>

#endif  // __Fuchsia__

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_anonymous {

class SomeProtocol;

}  // namespace test_anonymous

template <>
struct ::fidl::internal::WireOrdinal<::test_anonymous::SomeProtocol::SomeMethod> final {
  static constexpr uint64_t value = 2515914517457749720lu;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<::test_anonymous::SomeProtocol::SomeMethod> {
  static constexpr bool HasRequestPayload = true;
  using Request = ::test_anonymous::wire::SomeProtocolSomeMethodRequest;
  using Response = ::test_anonymous::wire::SomeProtocolSomeMethodResult;
  using DomainError = ::test_anonymous::wire::SomeProtocolSomeMethodError;

  using Completer = fidl::Completer<::fidl::internal::WireCompleterBase<::test_anonymous::SomeProtocol::SomeMethod>>;
  using Thenable = ::fidl::internal::WireThenableImpl<
      ::test_anonymous::SomeProtocol::SomeMethod,
      ::fidl::internal::OwnedEncodedMessage<
          ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::ChannelTransport>>;

  using BufferThenable = ::fidl::internal::WireThenableImpl<
      ::test_anonymous::SomeProtocol::SomeMethod,
      ::fidl::internal::UnownedEncodedMessage<
          ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::ChannelTransport>>;
};

#endif  // __Fuchsia__

namespace test_anonymous {

}  // namespace test_anonymous

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_anonymous::SomeProtocol> {
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_anonymous::SomeProtocol> final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(::fidl::WireServer<::test_anonymous::SomeProtocol>* impl, ::fidl::IncomingHeaderAndMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_anonymous::SomeProtocol>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod> final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::test_anonymous::wire::SomeProtocolSomeMethodRequest body;
  explicit TransactionalRequest(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member)
      : body(::test_anonymous::wire::SomeProtocolSomeMethodRequest{union_member, table_member}) {
    _InitHeader();
  }
  TransactionalRequest() {
    _InitHeader();
  }
  using ResponseType = ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>;

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 32 + sizeof(fidl_message_header_t);

  static void Encode(internal::WireEncoder* encoder, ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<fidl_message_header_t>() = value->header;
    WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest, WireCodingConstraintEmpty, IsRecursive>::Encode(
        encoder, &value->body, position + sizeof(fidl_message_header_t), recursion_depth);
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest, WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + sizeof(fidl_message_header_t), recursion_depth);
  }
};

#endif  // __Fuchsia__

template <>
struct ::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod> final : public ::test_anonymous::wire::SomeProtocolSomeMethodResult {
  explicit WireResponse(::test_anonymous::wire::SomeProtocolSomeMethodResult SomeProtocolSomeMethodResult) : ::test_anonymous::wire::SomeProtocolSomeMethodResult(SomeProtocolSomeMethodResult) {}
  WireResponse() = default;
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(
      internal::WireEncoder* encoder, ::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(
        encoder, value, position, recursion_depth);
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position, recursion_depth);
  }
};

template <>
struct ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod> final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod> body;
  explicit TransactionalResponse(::test_anonymous::wire::SomeProtocolSomeMethodResult SomeProtocolSomeMethodResult)
      : body(::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>(SomeProtocolSomeMethodResult)) {
    _InitHeader();
  }
  TransactionalResponse() {
    _InitHeader();
  }

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16 + sizeof(fidl_message_header_t);

  static void Encode(internal::WireEncoder* encoder, ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<fidl_message_header_t>() = value->header;
    WireCodingTraits<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>, WireCodingConstraintEmpty, IsRecursive>::Encode(
        encoder, &value->body, position + sizeof(fidl_message_header_t), recursion_depth);
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    WireCodingTraits<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>, WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + sizeof(fidl_message_header_t), recursion_depth);
  }
};

namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>> : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = FIDL_ALIGN(32 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(sizeof(::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>) == TypeTraits<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, body) == sizeof(fidl_message_header_t));
static_assert(sizeof(::test_anonymous::wire::SomeProtocolSomeMethodRequest) == TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest>::kPrimarySize);
static_assert(offsetof(::test_anonymous::wire::SomeProtocolSomeMethodRequest, union_member) == 0);
static_assert(offsetof(::test_anonymous::wire::SomeProtocolSomeMethodRequest, table_member) == 16);

#endif  // __Fuchsia__

template <>
struct IsFidlType<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> : public std::true_type {};
template <>
struct IsFidlType<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>> : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> {
  static constexpr bool kHasServerToClientBody = true;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = FIDL_ALIGN(16 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};

static_assert(sizeof(::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>) == TypeTraits<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>, header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>, body) == sizeof(fidl_message_header_t));
template <>
struct TypeTraits<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>> {
  static constexpr bool kHasServerToClientBody = true;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};
static_assert(sizeof(::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>) == TypeTraits<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>>::kPrimarySize);
#ifdef __Fuchsia__
}  // namespace fidl

template <>
struct ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> final
    : public ::fidl::internal::ChannelHandleStorageBase<::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>>> {
  static constexpr uint32_t kNumHandles =
      fidl::internal::ClampedHandleCount<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>, fidl::MessageDirection::kReceiving>();

  ::std::array<zx_handle_t, kNumHandles> handles_;
  ::std::array<fidl_channel_handle_metadata_t, kNumHandles> handle_metadata_;
};

template <>
struct ::fidl::internal::IncomingMessageStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> final
    : public ::fidl::internal::ChannelMessageStorageBase<::fidl::internal::IncomingMessageStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>>> {
  ::fidl::internal::InlineMessageBuffer<32> bytes_;
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> handles_storage_;
};
template <>
struct ::fidl::internal::IncomingEventsHandleStorage<::test_anonymous::SomeProtocol> final : public ::fidl::internal::ChannelHandleStorageBase<::fidl::internal::IncomingEventsHandleStorage<::test_anonymous::SomeProtocol>> {
 public:
  static constexpr uint32_t kNumHandles = 0;

  ::std::array<zx_handle_t, kNumHandles> handles_;
  ::std::array<fidl_channel_handle_metadata_t, kNumHandles> handle_metadata_;
};

template <>
struct ::fidl::internal::IncomingEventsStorage<::test_anonymous::SomeProtocol> final : public ::fidl::internal::ChannelMessageStorageBase<::fidl::internal::IncomingEventsStorage<::test_anonymous::SomeProtocol>> {
 public:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
  ::fidl::internal::IncomingEventsHandleStorage<::test_anonymous::SomeProtocol> handles_storage_;
};

template <>
struct ::fidl::internal::WireResultUnwrap<::test_anonymous::SomeProtocol::SomeMethod> {
  using Type = ::fit::result<::test_anonymous::wire::SomeProtocolSomeMethodError, ::test_anonymous::wire::SomeProtocolSomeMethodResponse*>;
};

template <>
class [[nodiscard]] ::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod> final : public ::fidl::BaseWireResult<::test_anonymous::SomeProtocol::SomeMethod> {
 public:
  WireResult(
      ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> client,
      ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>* request);

  explicit WireResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_anonymous::SomeProtocol::SomeMethod>(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult& operator=(WireResult&&) = delete;
  WireResult& operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
  ::fidl::internal::InlineMessageBuffer<32> bytes_;
  ::fidl::DecodedValue<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>> decoded_;
};

template <>
class [[nodiscard]] ::fidl::WireUnownedResult<::test_anonymous::SomeProtocol::SomeMethod> final : public ::fidl::BaseWireResult<::test_anonymous::SomeProtocol::SomeMethod> {
 public:
  explicit WireUnownedResult(::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>* request);
  explicit WireUnownedResult(::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>* response)
      : ::fidl::BaseWireResult<::test_anonymous::SomeProtocol::SomeMethod>(fidl::Status::Ok()), decoded_(response) {
    ExtractValueFromDecoded(decoded_.pointer());
  }

  explicit WireUnownedResult(
      ::fit::result<::fidl::Error, ::fidl::DecodedValue<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>>>&& decoded,
      ::fidl::internal::MessageStorageViewBase* storage_view) : ::fidl::BaseWireResult<::test_anonymous::SomeProtocol::SomeMethod>(::fidl::internal::StatusFromResult(decoded)) {
    if (decoded.is_ok()) {
      decoded_ = std::move(decoded.value());
      ExtractValueFromDecoded(decoded_.pointer());
    }
  }

  explicit WireUnownedResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_anonymous::SomeProtocol::SomeMethod>(result) {}
  WireUnownedResult(WireUnownedResult&&) = default;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult& operator=(WireUnownedResult&&) = default;
  WireUnownedResult& operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

 private:
  ::fidl::DecodedValue<::fidl::WireResponse<::test_anonymous::SomeProtocol::SomeMethod>> decoded_;
};

template <>
class ::fidl::internal::WireEventHandlerInterface<::test_anonymous::SomeProtocol> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fidl::WireAsyncEventHandler<::test_anonymous::SomeProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<::test_anonymous::SomeProtocol>, public ::fidl::internal::AsyncEventHandler {
 public:
  WireAsyncEventHandler() = default;
};

template <>
class ::fidl::WireSyncEventHandler<::test_anonymous::SomeProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<::test_anonymous::SomeProtocol>, public ::fidl::internal::SyncEventHandler {
 public:
  WireSyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the corresponding virtual
  // method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> client_end);
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_anonymous::SomeProtocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::WireEventHandlerInterface<::test_anonymous::SomeProtocol>> {
 public:
  explicit WireEventDispatcher(::fidl::internal::WireEventHandlerInterface<::test_anonymous::SomeProtocol>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

// Methods to make a sync FIDL call directly on an unowned handle or a
// const reference to a |::fidl::ClientEnd<::test_anonymous::SomeProtocol>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireSyncClientImpl<::test_anonymous::SomeProtocol> final : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireSyncClientImpl<::test_anonymous::SomeProtocol>> {
 public:
  // Allocates 128 bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod>
  SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member) {
    ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod> _request{union_member, table_member};
    return ::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod>(_client_end(), &_request);
  }

 private:
  ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

template <>
class ::fidl::internal::WireSyncBufferClientImpl<::test_anonymous::SomeProtocol> final : public ::fidl::internal::SyncEndpointBufferVeneer<::fidl::internal::WireSyncBufferClientImpl<::test_anonymous::SomeProtocol>> {
 public:
  // Caller provides the backing storage for FIDL message via an argument to `.buffer()`.
  ::fidl::WireUnownedResult<::test_anonymous::SomeProtocol::SomeMethod>
  SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member) {
    ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod> _request{union_member, table_member};
    return ::fidl::WireUnownedResult<::test_anonymous::SomeProtocol::SomeMethod>(_client_end(), _allocator(), &_request);
  }

 private:
  ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

template <>
class ::fidl::internal::WireCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod> : public ::fidl::internal::CompleterImplBase<::test_anonymous::SomeProtocol::SomeMethod> {
 public:
  using CompleterImplBase::CompleterImplBase;

  void Reply(::fit::result<::test_anonymous::wire::SomeProtocolSomeMethodError, ::test_anonymous::wire::SomeProtocolSomeMethodResponse*> result);
  void ReplySuccess(::test_anonymous::wire::BitsMember bits_member);
  void ReplyError(::test_anonymous::wire::SomeProtocolSomeMethodError error);

 private:
  void MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult SomeProtocolSomeMethodResult);
};

template <>
class ::fidl::internal::WireBufferCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod> : public ::fidl::internal::BufferCompleterImplBase {
 public:
  using BufferCompleterImplBase::BufferCompleterImplBase;

  void Reply(::fit::result<::test_anonymous::wire::SomeProtocolSomeMethodError, ::test_anonymous::wire::SomeProtocolSomeMethodResponse*> result);
  void ReplySuccess(::test_anonymous::wire::BitsMember bits_member);
  void ReplyError(::test_anonymous::wire::SomeProtocolSomeMethodError error);

 private:
  void MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult SomeProtocolSomeMethodResult);
};

template <>
class ::fidl::internal::WireCompleterBase<::test_anonymous::SomeProtocol::SomeMethod> : public ::fidl::CompleterBase, public ::fidl::internal::WireCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod> {
 public:
  WireCompleterBase(::fidl::Transaction* transaction, bool owned, bool expects_reply)
      : CompleterBase(transaction, owned, expects_reply),
        WireCompleterImpl(this) {}
  WireCompleterBase(WireCompleterBase&& other) noexcept
      : CompleterBase(std::move(other)), WireCompleterImpl(this) {}
  WireCompleterBase& operator=(WireCompleterBase&& other) noexcept {
    CompleterBase::operator=(std::move(other));
    WireCompleterImpl::_set_core(this);
    return *this;
  }
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |::fidl::ClientEnd<::test_anonymous::SomeProtocol>|
// and |::fidl::ServerEnd<::test_anonymous::SomeProtocol>|).
template <>
class ::fidl::WireServer<::test_anonymous::SomeProtocol> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_anonymous::SomeProtocol;

  using Handler = fidl::ProtocolHandler<::test_anonymous::SomeProtocol>;

  using SomeMethodCompleter = ::fidl::internal::WireCompleter<::test_anonymous::SomeProtocol::SomeMethod>;
  using SomeMethodRequestView = ::test_anonymous::wire::SomeProtocolSomeMethodRequest*;

  virtual void SomeMethod(
      ::test_anonymous::wire::SomeProtocolSomeMethodRequest* request,
      SomeMethodCompleter::Sync& completer) = 0;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_anonymous::SomeProtocol> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};
namespace fidl {

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_anonymous::SomeProtocol> : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_anonymous::SomeProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_anonymous::SomeProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
  // Allocates 96 bytes of request buffer on the stack. The callback is stored on the heap.
  ::fidl::internal::WireThenable<::test_anonymous::SomeProtocol::SomeMethod> SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member);
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_anonymous::SomeProtocol> : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<::test_anonymous::SomeProtocol> final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_anonymous::SomeProtocol> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;

  // Caller provides the backing storage for FIDL message.
  ::fidl::internal::WireBufferThenable<::test_anonymous::SomeProtocol::SomeMethod> SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member);
};
template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_anonymous::SomeProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_anonymous::SomeProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;

  // Allocates 128 bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod> SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member);
};
namespace fidl {

#endif  // __Fuchsia__

}  // namespace fidl

#ifdef __Fuchsia__
template <>
class ::fidl::internal::WireWeakEventSender<::test_anonymous::SomeProtocol> : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_anonymous::SomeProtocol> : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_anonymous::SomeProtocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireEventSender<::test_anonymous::SomeProtocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_anonymous::SomeProtocol>
    : public ::fidl::internal::SyncEndpointBufferVeneer<::fidl::internal::WireBufferEventSender<::test_anonymous::SomeProtocol>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop
