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

#include <fidl/test/protocols/llcpp/fidl.h>

#include <memory>

namespace llcpp {

namespace fidl {
namespace test {
namespace protocols {

void ::llcpp::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntax_ResponseAsStruct_Result) ==
                sizeof(fidl_xunion_t));
  static_assert(offsetof(WithErrorSyntax_ResponseAsStruct_Result, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(WithErrorSyntax_ResponseAsStruct_Result, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

void ::llcpp::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntax_ErrorAsPrimitive_Result) ==
                sizeof(fidl_xunion_t));
  static_assert(offsetof(WithErrorSyntax_ErrorAsPrimitive_Result, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(WithErrorSyntax_ErrorAsPrimitive_Result, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

namespace {

[[maybe_unused]] constexpr uint64_t kTransitional_Request_Ordinal =
    7121112290509197032lu;
extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestResponseTable;
[[maybe_unused]] constexpr uint64_t kTransitional_OneWay_Ordinal =
    1124136612964114085lu;
extern "C" const fidl_type_t fidl_test_protocols_TransitionalOneWayRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalOneWayResponseTable;
[[maybe_unused]] constexpr uint64_t kTransitional_Event_Ordinal =
    6033576734966581606lu;
extern "C" const fidl_type_t fidl_test_protocols_TransitionalEventRequestTable;
extern "C" const fidl_type_t fidl_test_protocols_TransitionalEventEventTable;

}  // namespace
Transitional::ResultOf::Request::Request(zx_handle_t _client, int64_t x) {
  RequestRequest::OwnedEncodedMessage _request(zx_txid_t(0), x);
  _request.GetOutgoingMessage().Call<RequestResponse>(
      _client, bytes_,
      RequestResponse::PrimarySize + RequestResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

Transitional::ResultOf::Request::Request(zx_handle_t _client, int64_t x,
                                         zx_time_t _deadline) {
  RequestRequest::OwnedEncodedMessage _request(zx_txid_t(0), x);
  _request.GetOutgoingMessage().Call<RequestResponse>(
      _client, bytes_,
      RequestResponse::PrimarySize + RequestResponse::MaxOutOfLine, _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

Transitional::UnownedResultOf::Request::Request(
    zx_handle_t _client, uint8_t* _request_bytes,
    uint32_t _request_byte_capacity, int64_t x, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  RequestRequest::UnownedEncodedMessage _request(_request_bytes,
                                                 _request_byte_capacity, 0, x);
  _request.GetOutgoingMessage().Call<RequestResponse>(_client, _response_bytes,
                                                      _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

Transitional::ResultOf::OneWay::OneWay(zx_handle_t _client, int64_t x) {
  OneWayRequest::OwnedEncodedMessage _request(zx_txid_t(0), x);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

Transitional::UnownedResultOf::OneWay::OneWay(zx_handle_t _client,
                                              uint8_t* _request_bytes,
                                              uint32_t _request_byte_capacity,
                                              int64_t x) {
  OneWayRequest::UnownedEncodedMessage _request(_request_bytes,
                                                _request_byte_capacity, 0, x);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

Transitional::ResultOf::Request Transitional::ClientImpl::Request_Sync(
    int64_t x) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::Request(_channel->handle(), x);
  }
  return Transitional::ResultOf::Request(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

Transitional::UnownedResultOf::Request Transitional::ClientImpl::Request_Sync(
    ::fidl::BufferSpan _request_buffer, int64_t x,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::Request(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, x,
        _response_buffer.data, _response_buffer.capacity);
  }
  return Transitional::UnownedResultOf::Request(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

Transitional::RequestResponseContext::RequestResponseContext()
    : ::fidl::internal::ResponseContext(RequestResponse::Type,
                                        kTransitional_Request_Ordinal) {}

void Transitional::RequestResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<RequestResponse*>(reply));
}

::fidl::Result Transitional::ClientImpl::Request(
    int64_t x, ::fit::callback<void(RequestResponse* response)> _cb) {
  class ResponseContext final : public RequestResponseContext {
   public:
    ResponseContext(::fit::callback<void(RequestResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(RequestResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(RequestResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  RequestRequest::OwnedEncodedMessage _request(_context->Txid(), x);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result Transitional::ClientImpl::Request(
    ::fidl::BufferSpan _request_buffer, int64_t x,
    RequestResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  RequestRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), x);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result Transitional::ClientImpl::OneWay(int64_t x) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ResultOf::OneWay(_channel->handle(), x);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

::fidl::Result Transitional::ClientImpl::OneWay(
    ::fidl::BufferSpan _request_buffer, int64_t x) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = UnownedResultOf::OneWay(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, x);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

std::optional<::fidl::UnbindInfo> Transitional::ClientImpl::DispatchEvent(
    fidl_incoming_msg_t* msg) {
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    case kTransitional_Event_Ordinal: {
      const char* error_message;
      zx_status_t status =
          fidl_decode_etc(EventResponse::Type, msg->bytes, msg->num_bytes,
                          msg->handles, msg->num_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
      }
      if (!handlers_.event) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                  ZX_ERR_NOT_SUPPORTED};
      }
      handlers_.event(reinterpret_cast<EventResponse*>(msg->bytes));
      break;
    }
    default:
      FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
      return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                ZX_ERR_NOT_SUPPORTED};
  }
  return {};
}

::fidl::Result Transitional::EventHandler::HandleOneEvent(
    ::zx::unowned_channel client_end) {
  zx_status_t status =
      client_end->wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                           ::zx::time::infinite(), nullptr);
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorWaitOneFailed);
  }
  constexpr uint32_t kReadAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::internal::ClampedMessageSize<
            EventResponse, ::fidl::MessageDirection::kReceiving>() >= x) {
      x = ::fidl::internal::ClampedMessageSize<
          EventResponse, ::fidl::MessageDirection::kReceiving>();
    }
    return x;
  })();
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (EventResponse::MaxNumHandles >= x) {
      x = EventResponse::MaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  ::fidl::internal::ByteStorage<kReadAllocSize> read_storage;
  uint8_t* read_bytes = read_storage.data();
  zx_handle_info_t read_handles[kHandleAllocSize];
  uint32_t actual_bytes;
  uint32_t actual_handles;
  status = client_end->read_etc(ZX_CHANNEL_READ_MAY_DISCARD, read_bytes,
                                read_handles, kReadAllocSize, kHandleAllocSize,
                                &actual_bytes, &actual_handles);
  if (status == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Result(Unknown(), nullptr);
  }
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorReadFailed);
  }
  if (actual_bytes < sizeof(fidl_message_header_t)) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(ZX_ERR_INVALID_ARGS, ::fidl::kErrorInvalidHeader);
  }
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(read_bytes);
  status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(status, ::fidl::kErrorInvalidHeader);
  }
  switch (hdr->ordinal) {
    case kTransitional_Event_Ordinal: {
      const char* error_message;
      zx_status_t status =
          fidl_decode_etc(EventResponse::Type, read_bytes, actual_bytes,
                          read_handles, actual_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      Event(reinterpret_cast<EventResponse*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    default: {
      FidlHandleInfoCloseMany(read_handles, actual_handles);
      return ::fidl::Result(Unknown(), nullptr);
    }
  }
}

namespace methods {

void TransitionalDispatchRequest(void* interface, void* bytes,
                                 ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<Transitional::RequestRequest*>(bytes);
  Transitional::Interface::RequestCompleter::Sync completer(txn);
  reinterpret_cast<Transitional::Interface*>(interface)->Request(
      std::move(message->x), completer);
}

void TransitionalDispatchOneWay(void* interface, void* bytes,
                                ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<Transitional::OneWayRequest*>(bytes);
  Transitional::Interface::OneWayCompleter::Sync completer(txn);
  reinterpret_cast<Transitional::Interface*>(interface)->OneWay(
      std::move(message->x), completer);
}

}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry Transitional[] = {
    {kTransitional_Request_Ordinal, Transitional::RequestRequest::Type,
     methods::TransitionalDispatchRequest},
    {kTransitional_OneWay_Ordinal, Transitional::OneWayRequest::Type,
     methods::TransitionalDispatchOneWay},
};

}  // namespace entries

::fidl::DispatchResult Transitional::TryDispatch(Interface* impl,
                                                 fidl_incoming_msg_t* msg,
                                                 ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries::Transitional,
      entries::Transitional + sizeof(entries::Transitional) /
                                  sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult Transitional::Dispatch(Interface* impl,
                                              fidl_incoming_msg_t* msg,
                                              ::fidl::Transaction* txn) {
  ::fidl::DispatchResult dispatch_result = TryDispatch(impl, msg, txn);
  if (dispatch_result == ::fidl::DispatchResult::kNotFound) {
    FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
    txn->InternalError(
        {::fidl::UnbindInfo::kUnexpectedMessage, ZX_ERR_NOT_SUPPORTED});
  }
  return dispatch_result;
}

::fidl::DispatchResult Transitional::Interface::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return Transitional::Dispatch(this, msg, txn);
}

::fidl::Result Transitional::Interface::RequestCompleterBase::Reply(int64_t y) {
  RequestResponse::OwnedEncodedMessage _response{y};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result Transitional::Interface::RequestCompleterBase::Reply(
    ::fidl::BufferSpan _buffer, int64_t y) {
  RequestResponse::UnownedEncodedMessage _response(_buffer.data,
                                                   _buffer.capacity, y);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

void Transitional::RequestRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kTransitional_Request_Ordinal);
}

void Transitional::RequestResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kTransitional_Request_Ordinal);
}

void Transitional::OneWayRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kTransitional_OneWay_Ordinal);
}

void Transitional::EventResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kTransitional_Event_Ordinal);
}

zx_status_t Transitional::EventSender::Event(int64_t x) const {
  EventResponse::OwnedEncodedMessage _response{x};
  _response.Write(server_end_.get());
  return _response.status();
}

zx_status_t Transitional::EventSender::Event(::fidl::BufferSpan _buffer,
                                             int64_t x) const {
  EventResponse::UnownedEncodedMessage _response(_buffer.data, _buffer.capacity,
                                                 x);
  _response.Write(server_end_.get());
  return _response.status();
}

namespace {

[[maybe_unused]] constexpr uint64_t kChannelProtocol_MethodA_Ordinal =
    565531679656837166lu;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodARequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodAResponseTable;
[[maybe_unused]] constexpr uint64_t kChannelProtocol_EventA_Ordinal =
    5963604044179602938lu;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventARequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventAEventTable;
[[maybe_unused]] constexpr uint64_t kChannelProtocol_MethodB_Ordinal =
    6746905632127147242lu;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBResponseTable;
[[maybe_unused]] constexpr uint64_t kChannelProtocol_TakeHandle_Ordinal =
    875219241480379432lu;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleResponseTable;
[[maybe_unused]] constexpr uint64_t kChannelProtocol_MutateSocket_Ordinal =
    9065806117349865322lu;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketResponseTable;

}  // namespace
ChannelProtocol::ResultOf::MethodA::MethodA(zx_handle_t _client, int64_t a,
                                            int64_t b) {
  MethodARequest::OwnedEncodedMessage _request(zx_txid_t(0), a, b);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::UnownedResultOf::MethodA::MethodA(
    zx_handle_t _client, uint8_t* _request_bytes,
    uint32_t _request_byte_capacity, int64_t a, int64_t b) {
  MethodARequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, a, b);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::ResultOf::MethodB::MethodB(zx_handle_t _client, int64_t a,
                                            int64_t b) {
  MethodBRequest::OwnedEncodedMessage _request(zx_txid_t(0), a, b);
  _request.GetOutgoingMessage().Call<MethodBResponse>(
      _client, bytes_,
      MethodBResponse::PrimarySize + MethodBResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::ResultOf::MethodB::MethodB(zx_handle_t _client, int64_t a,
                                            int64_t b, zx_time_t _deadline) {
  MethodBRequest::OwnedEncodedMessage _request(zx_txid_t(0), a, b);
  _request.GetOutgoingMessage().Call<MethodBResponse>(
      _client, bytes_,
      MethodBResponse::PrimarySize + MethodBResponse::MaxOutOfLine, _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::UnownedResultOf::MethodB::MethodB(
    zx_handle_t _client, uint8_t* _request_bytes,
    uint32_t _request_byte_capacity, int64_t a, int64_t b,
    uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  MethodBRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, a, b);
  _request.GetOutgoingMessage().Call<MethodBResponse>(_client, _response_bytes,
                                                      _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::ResultOf::TakeHandle::TakeHandle(zx_handle_t _client,
                                                  ::zx::handle& h) {
  TakeHandleRequest::OwnedEncodedMessage _request(zx_txid_t(0), h);
  _request.GetOutgoingMessage().Call<TakeHandleResponse>(
      _client, bytes_,
      TakeHandleResponse::PrimarySize + TakeHandleResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::ResultOf::TakeHandle::TakeHandle(zx_handle_t _client,
                                                  ::zx::handle& h,
                                                  zx_time_t _deadline) {
  TakeHandleRequest::OwnedEncodedMessage _request(zx_txid_t(0), h);
  _request.GetOutgoingMessage().Call<TakeHandleResponse>(
      _client, bytes_,
      TakeHandleResponse::PrimarySize + TakeHandleResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::UnownedResultOf::TakeHandle::TakeHandle(
    zx_handle_t _client, uint8_t* _request_bytes,
    uint32_t _request_byte_capacity, ::zx::handle& h, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  TakeHandleRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, h);
  _request.GetOutgoingMessage().Call<TakeHandleResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::ResultOf::MutateSocket::MutateSocket(zx_handle_t _client,
                                                      ::zx::socket& a) {
  MutateSocketRequest::OwnedEncodedMessage _request(zx_txid_t(0), a);
  _request.GetOutgoingMessage().Call<MutateSocketResponse>(
      _client, bytes_,
      MutateSocketResponse::PrimarySize + MutateSocketResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::ResultOf::MutateSocket::MutateSocket(zx_handle_t _client,
                                                      ::zx::socket& a,
                                                      zx_time_t _deadline) {
  MutateSocketRequest::OwnedEncodedMessage _request(zx_txid_t(0), a);
  _request.GetOutgoingMessage().Call<MutateSocketResponse>(
      _client, bytes_,
      MutateSocketResponse::PrimarySize + MutateSocketResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

ChannelProtocol::UnownedResultOf::MutateSocket::MutateSocket(
    zx_handle_t _client, uint8_t* _request_bytes,
    uint32_t _request_byte_capacity, ::zx::socket& a, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  MutateSocketRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, a);
  _request.GetOutgoingMessage().Call<MutateSocketResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::Result ChannelProtocol::ClientImpl::MethodA(int64_t a, int64_t b) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ResultOf::MethodA(_channel->handle(), a, b);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

::fidl::Result ChannelProtocol::ClientImpl::MethodA(
    ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res =
        UnownedResultOf::MethodA(_channel->handle(), _request_buffer.data,
                                 _request_buffer.capacity, a, b);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

ChannelProtocol::ResultOf::MethodB ChannelProtocol::ClientImpl::MethodB_Sync(
    int64_t a, int64_t b) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::MethodB(_channel->handle(), a, b);
  }
  return ChannelProtocol::ResultOf::MethodB(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

ChannelProtocol::UnownedResultOf::MethodB
ChannelProtocol::ClientImpl::MethodB_Sync(::fidl::BufferSpan _request_buffer,
                                          int64_t a, int64_t b,
                                          ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::MethodB(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, a,
        b, _response_buffer.data, _response_buffer.capacity);
  }
  return ChannelProtocol::UnownedResultOf::MethodB(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

ChannelProtocol::MethodBResponseContext::MethodBResponseContext()
    : ::fidl::internal::ResponseContext(MethodBResponse::Type,
                                        kChannelProtocol_MethodB_Ordinal) {}

void ChannelProtocol::MethodBResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<MethodBResponse*>(reply));
}

::fidl::Result ChannelProtocol::ClientImpl::MethodB(
    int64_t a, int64_t b,
    ::fit::callback<void(MethodBResponse* response)> _cb) {
  class ResponseContext final : public MethodBResponseContext {
   public:
    ResponseContext(::fit::callback<void(MethodBResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(MethodBResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(MethodBResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  MethodBRequest::OwnedEncodedMessage _request(_context->Txid(), a, b);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result ChannelProtocol::ClientImpl::MethodB(
    ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
    MethodBResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  MethodBRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), a, b);
  return _request.GetOutgoingMessage().Write(this, _context);
}

ChannelProtocol::ResultOf::TakeHandle
ChannelProtocol::ClientImpl::TakeHandle_Sync(::zx::handle h) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::TakeHandle(_channel->handle(), h);
  }
  return ChannelProtocol::ResultOf::TakeHandle(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

ChannelProtocol::UnownedResultOf::TakeHandle
ChannelProtocol::ClientImpl::TakeHandle_Sync(
    ::fidl::BufferSpan _request_buffer, ::zx::handle h,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::TakeHandle(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, h,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ChannelProtocol::UnownedResultOf::TakeHandle(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

ChannelProtocol::TakeHandleResponseContext::TakeHandleResponseContext()
    : ::fidl::internal::ResponseContext(TakeHandleResponse::Type,
                                        kChannelProtocol_TakeHandle_Ordinal) {}

void ChannelProtocol::TakeHandleResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<TakeHandleResponse*>(reply));
}

::fidl::Result ChannelProtocol::ClientImpl::TakeHandle(
    ::zx::handle h, ::fit::callback<void(TakeHandleResponse* response)> _cb) {
  class ResponseContext final : public TakeHandleResponseContext {
   public:
    ResponseContext(::fit::callback<void(TakeHandleResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(TakeHandleResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(TakeHandleResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  TakeHandleRequest::OwnedEncodedMessage _request(_context->Txid(), h);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result ChannelProtocol::ClientImpl::TakeHandle(
    ::fidl::BufferSpan _request_buffer, ::zx::handle h,
    TakeHandleResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  TakeHandleRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), h);
  return _request.GetOutgoingMessage().Write(this, _context);
}

ChannelProtocol::ResultOf::MutateSocket
ChannelProtocol::ClientImpl::MutateSocket_Sync(::zx::socket a) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::MutateSocket(_channel->handle(), a);
  }
  return ChannelProtocol::ResultOf::MutateSocket(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

ChannelProtocol::UnownedResultOf::MutateSocket
ChannelProtocol::ClientImpl::MutateSocket_Sync(
    ::fidl::BufferSpan _request_buffer, ::zx::socket a,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::MutateSocket(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, a,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ChannelProtocol::UnownedResultOf::MutateSocket(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

ChannelProtocol::MutateSocketResponseContext::MutateSocketResponseContext()
    : ::fidl::internal::ResponseContext(
          MutateSocketResponse::Type, kChannelProtocol_MutateSocket_Ordinal) {}

void ChannelProtocol::MutateSocketResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<MutateSocketResponse*>(reply));
}

::fidl::Result ChannelProtocol::ClientImpl::MutateSocket(
    ::zx::socket a, ::fit::callback<void(MutateSocketResponse* response)> _cb) {
  class ResponseContext final : public MutateSocketResponseContext {
   public:
    ResponseContext(::fit::callback<void(MutateSocketResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(MutateSocketResponse* response) override {
      cb_(response);

      response->_CloseHandles();

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(MutateSocketResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  MutateSocketRequest::OwnedEncodedMessage _request(_context->Txid(), a);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result ChannelProtocol::ClientImpl::MutateSocket(
    ::fidl::BufferSpan _request_buffer, ::zx::socket a,
    MutateSocketResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  MutateSocketRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), a);
  return _request.GetOutgoingMessage().Write(this, _context);
}

std::optional<::fidl::UnbindInfo> ChannelProtocol::ClientImpl::DispatchEvent(
    fidl_incoming_msg_t* msg) {
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    case kChannelProtocol_EventA_Ordinal: {
      const char* error_message;
      zx_status_t status =
          fidl_decode_etc(EventAResponse::Type, msg->bytes, msg->num_bytes,
                          msg->handles, msg->num_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
      }
      if (!handlers_.event_a) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                  ZX_ERR_NOT_SUPPORTED};
      }
      handlers_.event_a(reinterpret_cast<EventAResponse*>(msg->bytes));
      break;
    }
    default:
      FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
      return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                ZX_ERR_NOT_SUPPORTED};
  }
  return {};
}

::fidl::Result ChannelProtocol::EventHandler::HandleOneEvent(
    ::zx::unowned_channel client_end) {
  zx_status_t status =
      client_end->wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                           ::zx::time::infinite(), nullptr);
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorWaitOneFailed);
  }
  constexpr uint32_t kReadAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::internal::ClampedMessageSize<
            EventAResponse, ::fidl::MessageDirection::kReceiving>() >= x) {
      x = ::fidl::internal::ClampedMessageSize<
          EventAResponse, ::fidl::MessageDirection::kReceiving>();
    }
    return x;
  })();
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (EventAResponse::MaxNumHandles >= x) {
      x = EventAResponse::MaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  ::fidl::internal::ByteStorage<kReadAllocSize> read_storage;
  uint8_t* read_bytes = read_storage.data();
  zx_handle_info_t read_handles[kHandleAllocSize];
  uint32_t actual_bytes;
  uint32_t actual_handles;
  status = client_end->read_etc(ZX_CHANNEL_READ_MAY_DISCARD, read_bytes,
                                read_handles, kReadAllocSize, kHandleAllocSize,
                                &actual_bytes, &actual_handles);
  if (status == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Result(Unknown(), nullptr);
  }
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorReadFailed);
  }
  if (actual_bytes < sizeof(fidl_message_header_t)) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(ZX_ERR_INVALID_ARGS, ::fidl::kErrorInvalidHeader);
  }
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(read_bytes);
  status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(status, ::fidl::kErrorInvalidHeader);
  }
  switch (hdr->ordinal) {
    case kChannelProtocol_EventA_Ordinal: {
      const char* error_message;
      zx_status_t status =
          fidl_decode_etc(EventAResponse::Type, read_bytes, actual_bytes,
                          read_handles, actual_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      EventA(reinterpret_cast<EventAResponse*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    default: {
      FidlHandleInfoCloseMany(read_handles, actual_handles);
      return ::fidl::Result(Unknown(), nullptr);
    }
  }
}

namespace methods {

void ChannelProtocolDispatchMethodA(void* interface, void* bytes,
                                    ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<ChannelProtocol::MethodARequest*>(bytes);
  ChannelProtocol::Interface::MethodACompleter::Sync completer(txn);
  reinterpret_cast<ChannelProtocol::Interface*>(interface)->MethodA(
      std::move(message->a), std::move(message->b), completer);
}

void ChannelProtocolDispatchMethodB(void* interface, void* bytes,
                                    ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<ChannelProtocol::MethodBRequest*>(bytes);
  ChannelProtocol::Interface::MethodBCompleter::Sync completer(txn);
  reinterpret_cast<ChannelProtocol::Interface*>(interface)->MethodB(
      std::move(message->a), std::move(message->b), completer);
}

void ChannelProtocolDispatchTakeHandle(void* interface, void* bytes,
                                       ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<ChannelProtocol::TakeHandleRequest*>(bytes);
  ChannelProtocol::Interface::TakeHandleCompleter::Sync completer(txn);
  reinterpret_cast<ChannelProtocol::Interface*>(interface)->TakeHandle(
      std::move(message->h), completer);
}

void ChannelProtocolDispatchMutateSocket(void* interface, void* bytes,
                                         ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<ChannelProtocol::MutateSocketRequest*>(bytes);
  ChannelProtocol::Interface::MutateSocketCompleter::Sync completer(txn);
  reinterpret_cast<ChannelProtocol::Interface*>(interface)->MutateSocket(
      std::move(message->a), completer);
}

}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry ChannelProtocol[] = {
    {kChannelProtocol_MethodA_Ordinal, ChannelProtocol::MethodARequest::Type,
     methods::ChannelProtocolDispatchMethodA},
    {kChannelProtocol_MethodB_Ordinal, ChannelProtocol::MethodBRequest::Type,
     methods::ChannelProtocolDispatchMethodB},
    {kChannelProtocol_TakeHandle_Ordinal,
     ChannelProtocol::TakeHandleRequest::Type,
     methods::ChannelProtocolDispatchTakeHandle},
    {kChannelProtocol_MutateSocket_Ordinal,
     ChannelProtocol::MutateSocketRequest::Type,
     methods::ChannelProtocolDispatchMutateSocket},
};

}  // namespace entries

::fidl::DispatchResult ChannelProtocol::TryDispatch(Interface* impl,
                                                    fidl_incoming_msg_t* msg,
                                                    ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries::ChannelProtocol,
      entries::ChannelProtocol + sizeof(entries::ChannelProtocol) /
                                     sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult ChannelProtocol::Dispatch(Interface* impl,
                                                 fidl_incoming_msg_t* msg,
                                                 ::fidl::Transaction* txn) {
  ::fidl::DispatchResult dispatch_result = TryDispatch(impl, msg, txn);
  if (dispatch_result == ::fidl::DispatchResult::kNotFound) {
    FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
    txn->InternalError(
        {::fidl::UnbindInfo::kUnexpectedMessage, ZX_ERR_NOT_SUPPORTED});
  }
  return dispatch_result;
}

::fidl::DispatchResult ChannelProtocol::Interface::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ChannelProtocol::Dispatch(this, msg, txn);
}

::fidl::Result ChannelProtocol::Interface::MethodBCompleterBase::Reply(
    int64_t result) {
  MethodBResponse::OwnedEncodedMessage _response{result};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result ChannelProtocol::Interface::MethodBCompleterBase::Reply(
    ::fidl::BufferSpan _buffer, int64_t result) {
  MethodBResponse::UnownedEncodedMessage _response(_buffer.data,
                                                   _buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result ChannelProtocol::Interface::TakeHandleCompleterBase::Reply() {
  TakeHandleResponse::OwnedEncodedMessage _response{};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result ChannelProtocol::Interface::MutateSocketCompleterBase::Reply(
    ::zx::socket b) {
  MutateSocketResponse::OwnedEncodedMessage _response{b};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result ChannelProtocol::Interface::MutateSocketCompleterBase::Reply(
    ::fidl::BufferSpan _buffer, ::zx::socket b) {
  MutateSocketResponse::UnownedEncodedMessage _response(_buffer.data,
                                                        _buffer.capacity, b);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

void ChannelProtocol::MethodARequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kChannelProtocol_MethodA_Ordinal);
}

void ChannelProtocol::EventAResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kChannelProtocol_EventA_Ordinal);
}

void ChannelProtocol::MethodBRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kChannelProtocol_MethodB_Ordinal);
}

void ChannelProtocol::MethodBResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kChannelProtocol_MethodB_Ordinal);
}

void ChannelProtocol::TakeHandleRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kChannelProtocol_TakeHandle_Ordinal);
}

void ChannelProtocol::TakeHandleRequest::_CloseHandles() { h.reset(); }

void ChannelProtocol::TakeHandleResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kChannelProtocol_TakeHandle_Ordinal);
}

void ChannelProtocol::MutateSocketRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kChannelProtocol_MutateSocket_Ordinal);
}

void ChannelProtocol::MutateSocketRequest::_CloseHandles() { a.reset(); }

void ChannelProtocol::MutateSocketResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kChannelProtocol_MutateSocket_Ordinal);
}

void ChannelProtocol::MutateSocketResponse::_CloseHandles() { b.reset(); }

zx_status_t ChannelProtocol::EventSender::EventA(int64_t a, int64_t b) const {
  EventAResponse::OwnedEncodedMessage _response{a, b};
  _response.Write(server_end_.get());
  return _response.status();
}

zx_status_t ChannelProtocol::EventSender::EventA(::fidl::BufferSpan _buffer,
                                                 int64_t a, int64_t b) const {
  EventAResponse::UnownedEncodedMessage _response(_buffer.data,
                                                  _buffer.capacity, a, b);
  _response.Write(server_end_.get());
  return _response.status();
}

namespace {

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal =
        7699066378708085668lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseResponseTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal =
        4641225961522096302lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseResponseTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal =
        4935493674668456948lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal =
        8985942600963248509lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseResponseTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal =
        7344052883704365182lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseResponseTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal =
        2103802322332450033lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal =
        1323081535741489193lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseEventTable;
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_OnWithResponse_Ordinal =
        1691906546593908418lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseEventTable;

}  // namespace
WithAndWithoutRequestResponse::ResultOf::NoRequestNoResponse::
    NoRequestNoResponse(zx_handle_t _client) {
  NoRequestNoResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::NoRequestEmptyResponse::
    NoRequestEmptyResponse(zx_handle_t _client) {
  NoRequestEmptyResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<NoRequestEmptyResponseResponse>(
      _client, bytes_,
      NoRequestEmptyResponseResponse::PrimarySize +
          NoRequestEmptyResponseResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::NoRequestEmptyResponse::
    NoRequestEmptyResponse(zx_handle_t _client, zx_time_t _deadline) {
  NoRequestEmptyResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<NoRequestEmptyResponseResponse>(
      _client, bytes_,
      NoRequestEmptyResponseResponse::PrimarySize +
          NoRequestEmptyResponseResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::NoRequestWithResponse::
    NoRequestWithResponse(zx_handle_t _client)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  NoRequestWithResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<NoRequestWithResponseResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::NoRequestWithResponse::
    NoRequestWithResponse(zx_handle_t _client, zx_time_t _deadline)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  NoRequestWithResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<NoRequestWithResponseResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES, _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::UnownedResultOf::NoRequestWithResponse::
    NoRequestWithResponse(zx_handle_t _client, uint8_t* _response_bytes,
                          uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  NoRequestWithResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<NoRequestWithResponseResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::WithRequestNoResponse::
    WithRequestNoResponse(zx_handle_t _client, const ::fidl::StringView& arg) {
  WithRequestNoResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0), arg);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::UnownedResultOf::WithRequestNoResponse::
    WithRequestNoResponse(zx_handle_t _client, uint8_t* _request_bytes,
                          uint32_t _request_byte_capacity,
                          const ::fidl::StringView& arg) {
  WithRequestNoResponseRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, arg);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::WithRequestEmptyResponse::
    WithRequestEmptyResponse(zx_handle_t _client,
                             const ::fidl::StringView& arg) {
  WithRequestEmptyResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0),
                                                                arg);
  _request.GetOutgoingMessage().Call<WithRequestEmptyResponseResponse>(
      _client, bytes_,
      WithRequestEmptyResponseResponse::PrimarySize +
          WithRequestEmptyResponseResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::WithRequestEmptyResponse::
    WithRequestEmptyResponse(zx_handle_t _client, const ::fidl::StringView& arg,
                             zx_time_t _deadline) {
  WithRequestEmptyResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0),
                                                                arg);
  _request.GetOutgoingMessage().Call<WithRequestEmptyResponseResponse>(
      _client, bytes_,
      WithRequestEmptyResponseResponse::PrimarySize +
          WithRequestEmptyResponseResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::UnownedResultOf::WithRequestEmptyResponse::
    WithRequestEmptyResponse(zx_handle_t _client, uint8_t* _request_bytes,
                             uint32_t _request_byte_capacity,
                             const ::fidl::StringView& arg,
                             uint8_t* _response_bytes,
                             uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  WithRequestEmptyResponseRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, arg);
  _request.GetOutgoingMessage().Call<WithRequestEmptyResponseResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::WithRequestWithResponse::
    WithRequestWithResponse(zx_handle_t _client, const ::fidl::StringView& arg)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  WithRequestWithResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0),
                                                               arg);
  _request.GetOutgoingMessage().Call<WithRequestWithResponseResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::ResultOf::WithRequestWithResponse::
    WithRequestWithResponse(zx_handle_t _client, const ::fidl::StringView& arg,
                            zx_time_t _deadline)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  WithRequestWithResponseRequest::OwnedEncodedMessage _request(zx_txid_t(0),
                                                               arg);
  _request.GetOutgoingMessage().Call<WithRequestWithResponseResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES, _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithAndWithoutRequestResponse::UnownedResultOf::WithRequestWithResponse::
    WithRequestWithResponse(zx_handle_t _client, uint8_t* _request_bytes,
                            uint32_t _request_byte_capacity,
                            const ::fidl::StringView& arg,
                            uint8_t* _response_bytes,
                            uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  WithRequestWithResponseRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, arg);
  _request.GetOutgoingMessage().Call<WithRequestWithResponseResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::NoRequestNoResponse() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ResultOf::NoRequestNoResponse(_channel->handle());
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

WithAndWithoutRequestResponse::ResultOf::NoRequestEmptyResponse
WithAndWithoutRequestResponse::ClientImpl::NoRequestEmptyResponse_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::NoRequestEmptyResponse(_channel->handle());
  }
  return WithAndWithoutRequestResponse::ResultOf::NoRequestEmptyResponse(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::NoRequestEmptyResponseResponseContext::
    NoRequestEmptyResponseResponseContext()
    : ::fidl::internal::ResponseContext(
          NoRequestEmptyResponseResponse::Type,
          kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal) {}

void WithAndWithoutRequestResponse::NoRequestEmptyResponseResponseContext::
    OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<NoRequestEmptyResponseResponse*>(reply));
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::NoRequestEmptyResponse(
    ::fit::callback<void(NoRequestEmptyResponseResponse* response)> _cb) {
  class ResponseContext final : public NoRequestEmptyResponseResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(NoRequestEmptyResponseResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(NoRequestEmptyResponseResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(NoRequestEmptyResponseResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  NoRequestEmptyResponseRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::NoRequestEmptyResponse(
    NoRequestEmptyResponseResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  NoRequestEmptyResponseRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

WithAndWithoutRequestResponse::ResultOf::NoRequestWithResponse
WithAndWithoutRequestResponse::ClientImpl::NoRequestWithResponse_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::NoRequestWithResponse(_channel->handle());
  }
  return WithAndWithoutRequestResponse::ResultOf::NoRequestWithResponse(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::UnownedResultOf::NoRequestWithResponse
WithAndWithoutRequestResponse::ClientImpl::NoRequestWithResponse_Sync(
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::NoRequestWithResponse(
        _channel->handle(), _response_buffer.data, _response_buffer.capacity);
  }
  return WithAndWithoutRequestResponse::UnownedResultOf::NoRequestWithResponse(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::NoRequestWithResponseResponseContext::
    NoRequestWithResponseResponseContext()
    : ::fidl::internal::ResponseContext(
          NoRequestWithResponseResponse::Type,
          kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal) {}

void WithAndWithoutRequestResponse::NoRequestWithResponseResponseContext::
    OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<NoRequestWithResponseResponse*>(reply));
}

::fidl::Result WithAndWithoutRequestResponse::ClientImpl::NoRequestWithResponse(
    ::fit::callback<void(NoRequestWithResponseResponse* response)> _cb) {
  class ResponseContext final : public NoRequestWithResponseResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(NoRequestWithResponseResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(NoRequestWithResponseResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(NoRequestWithResponseResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  NoRequestWithResponseRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result WithAndWithoutRequestResponse::ClientImpl::NoRequestWithResponse(
    NoRequestWithResponseResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  NoRequestWithResponseRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result WithAndWithoutRequestResponse::ClientImpl::WithRequestNoResponse(
    ::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ResultOf::WithRequestNoResponse(_channel->handle(), arg);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

::fidl::Result WithAndWithoutRequestResponse::ClientImpl::WithRequestNoResponse(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = UnownedResultOf::WithRequestNoResponse(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity,
        arg);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

WithAndWithoutRequestResponse::ResultOf::WithRequestEmptyResponse
WithAndWithoutRequestResponse::ClientImpl::WithRequestEmptyResponse_Sync(
    ::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::WithRequestEmptyResponse(_channel->handle(), arg);
  }
  return WithAndWithoutRequestResponse::ResultOf::WithRequestEmptyResponse(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::UnownedResultOf::WithRequestEmptyResponse
WithAndWithoutRequestResponse::ClientImpl::WithRequestEmptyResponse_Sync(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::WithRequestEmptyResponse(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }
  return WithAndWithoutRequestResponse::UnownedResultOf::
      WithRequestEmptyResponse(
          ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::WithRequestEmptyResponseResponseContext::
    WithRequestEmptyResponseResponseContext()
    : ::fidl::internal::ResponseContext(
          WithRequestEmptyResponseResponse::Type,
          kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal) {}

void WithAndWithoutRequestResponse::WithRequestEmptyResponseResponseContext::
    OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<WithRequestEmptyResponseResponse*>(reply));
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::WithRequestEmptyResponse(
    ::fidl::StringView arg,
    ::fit::callback<void(WithRequestEmptyResponseResponse* response)> _cb) {
  class ResponseContext final : public WithRequestEmptyResponseResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(WithRequestEmptyResponseResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(WithRequestEmptyResponseResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(WithRequestEmptyResponseResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  WithRequestEmptyResponseRequest::OwnedEncodedMessage _request(
      _context->Txid(), arg);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::WithRequestEmptyResponse(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
    WithRequestEmptyResponseResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  WithRequestEmptyResponseRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), arg);
  return _request.GetOutgoingMessage().Write(this, _context);
}

WithAndWithoutRequestResponse::ResultOf::WithRequestWithResponse
WithAndWithoutRequestResponse::ClientImpl::WithRequestWithResponse_Sync(
    ::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::WithRequestWithResponse(_channel->handle(), arg);
  }
  return WithAndWithoutRequestResponse::ResultOf::WithRequestWithResponse(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::UnownedResultOf::WithRequestWithResponse
WithAndWithoutRequestResponse::ClientImpl::WithRequestWithResponse_Sync(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::WithRequestWithResponse(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }
  return WithAndWithoutRequestResponse::UnownedResultOf::
      WithRequestWithResponse(
          ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithAndWithoutRequestResponse::WithRequestWithResponseResponseContext::
    WithRequestWithResponseResponseContext()
    : ::fidl::internal::ResponseContext(
          WithRequestWithResponseResponse::Type,
          kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal) {}

void WithAndWithoutRequestResponse::WithRequestWithResponseResponseContext::
    OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<WithRequestWithResponseResponse*>(reply));
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::WithRequestWithResponse(
    ::fidl::StringView arg,
    ::fit::callback<void(WithRequestWithResponseResponse* response)> _cb) {
  class ResponseContext final : public WithRequestWithResponseResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(WithRequestWithResponseResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(WithRequestWithResponseResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(WithRequestWithResponseResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  WithRequestWithResponseRequest::OwnedEncodedMessage _request(_context->Txid(),
                                                               arg);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result
WithAndWithoutRequestResponse::ClientImpl::WithRequestWithResponse(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
    WithRequestWithResponseResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  WithRequestWithResponseRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), arg);
  return _request.GetOutgoingMessage().Write(this, _context);
}

std::optional<::fidl::UnbindInfo>
WithAndWithoutRequestResponse::ClientImpl::DispatchEvent(
    fidl_incoming_msg_t* msg) {
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    case kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          OnEmptyResponseResponse::Type, msg->bytes, msg->num_bytes,
          msg->handles, msg->num_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
      }
      if (!handlers_.on_empty_response) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                  ZX_ERR_NOT_SUPPORTED};
      }
      handlers_.on_empty_response();
      break;
    }
    case kWithAndWithoutRequestResponse_OnWithResponse_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          OnWithResponseResponse::Type, msg->bytes, msg->num_bytes,
          msg->handles, msg->num_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
      }
      if (!handlers_.on_with_response) {
        return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                  ZX_ERR_NOT_SUPPORTED};
      }
      handlers_.on_with_response(
          reinterpret_cast<OnWithResponseResponse*>(msg->bytes));
      break;
    }
    default:
      FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
      return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                ZX_ERR_NOT_SUPPORTED};
  }
  return {};
}

::fidl::Result WithAndWithoutRequestResponse::EventHandler::HandleOneEvent(
    ::zx::unowned_channel client_end) {
  zx_status_t status =
      client_end->wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                           ::zx::time::infinite(), nullptr);
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorWaitOneFailed);
  }
  constexpr uint32_t kReadAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::internal::ClampedMessageSize<
            OnEmptyResponseResponse, ::fidl::MessageDirection::kReceiving>() >=
        x) {
      x = ::fidl::internal::ClampedMessageSize<
          OnEmptyResponseResponse, ::fidl::MessageDirection::kReceiving>();
    }
    if (::fidl::internal::ClampedMessageSize<
            OnWithResponseResponse, ::fidl::MessageDirection::kReceiving>() >=
        x) {
      x = ::fidl::internal::ClampedMessageSize<
          OnWithResponseResponse, ::fidl::MessageDirection::kReceiving>();
    }
    return x;
  })();
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (OnEmptyResponseResponse::MaxNumHandles >= x) {
      x = OnEmptyResponseResponse::MaxNumHandles;
    }
    if (OnWithResponseResponse::MaxNumHandles >= x) {
      x = OnWithResponseResponse::MaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  ::fidl::internal::ByteStorage<kReadAllocSize> read_storage;
  uint8_t* read_bytes = read_storage.data();
  zx_handle_info_t read_handles[kHandleAllocSize];
  uint32_t actual_bytes;
  uint32_t actual_handles;
  status = client_end->read_etc(ZX_CHANNEL_READ_MAY_DISCARD, read_bytes,
                                read_handles, kReadAllocSize, kHandleAllocSize,
                                &actual_bytes, &actual_handles);
  if (status == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Result(Unknown(), nullptr);
  }
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorReadFailed);
  }
  if (actual_bytes < sizeof(fidl_message_header_t)) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(ZX_ERR_INVALID_ARGS, ::fidl::kErrorInvalidHeader);
  }
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(read_bytes);
  status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(status, ::fidl::kErrorInvalidHeader);
  }
  switch (hdr->ordinal) {
    case kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          OnEmptyResponseResponse::Type, read_bytes, actual_bytes, read_handles,
          actual_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      OnEmptyResponse(reinterpret_cast<OnEmptyResponseResponse*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    case kWithAndWithoutRequestResponse_OnWithResponse_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          OnWithResponseResponse::Type, read_bytes, actual_bytes, read_handles,
          actual_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      OnWithResponse(reinterpret_cast<OnWithResponseResponse*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    default: {
      FidlHandleInfoCloseMany(read_handles, actual_handles);
      return ::fidl::Result(Unknown(), nullptr);
    }
  }
}

namespace methods {

void WithAndWithoutRequestResponseDispatchNoRequestNoResponse(
    void* interface, void* bytes, ::fidl::Transaction* txn) {
  WithAndWithoutRequestResponse::Interface::NoRequestNoResponseCompleter::Sync
      completer(txn);
  reinterpret_cast<WithAndWithoutRequestResponse::Interface*>(interface)
      ->NoRequestNoResponse(completer);
}

void WithAndWithoutRequestResponseDispatchNoRequestEmptyResponse(
    void* interface, void* bytes, ::fidl::Transaction* txn) {
  WithAndWithoutRequestResponse::Interface::NoRequestEmptyResponseCompleter::
      Sync completer(txn);
  reinterpret_cast<WithAndWithoutRequestResponse::Interface*>(interface)
      ->NoRequestEmptyResponse(completer);
}

void WithAndWithoutRequestResponseDispatchNoRequestWithResponse(
    void* interface, void* bytes, ::fidl::Transaction* txn) {
  WithAndWithoutRequestResponse::Interface::NoRequestWithResponseCompleter::Sync
      completer(txn);
  reinterpret_cast<WithAndWithoutRequestResponse::Interface*>(interface)
      ->NoRequestWithResponse(completer);
}

void WithAndWithoutRequestResponseDispatchWithRequestNoResponse(
    void* interface, void* bytes, ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<
      WithAndWithoutRequestResponse::WithRequestNoResponseRequest*>(bytes);
  WithAndWithoutRequestResponse::Interface::WithRequestNoResponseCompleter::Sync
      completer(txn);
  reinterpret_cast<WithAndWithoutRequestResponse::Interface*>(interface)
      ->WithRequestNoResponse(std::move(message->arg), completer);
}

void WithAndWithoutRequestResponseDispatchWithRequestEmptyResponse(
    void* interface, void* bytes, ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<
      WithAndWithoutRequestResponse::WithRequestEmptyResponseRequest*>(bytes);
  WithAndWithoutRequestResponse::Interface::WithRequestEmptyResponseCompleter::
      Sync completer(txn);
  reinterpret_cast<WithAndWithoutRequestResponse::Interface*>(interface)
      ->WithRequestEmptyResponse(std::move(message->arg), completer);
}

void WithAndWithoutRequestResponseDispatchWithRequestWithResponse(
    void* interface, void* bytes, ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<
      WithAndWithoutRequestResponse::WithRequestWithResponseRequest*>(bytes);
  WithAndWithoutRequestResponse::Interface::WithRequestWithResponseCompleter::
      Sync completer(txn);
  reinterpret_cast<WithAndWithoutRequestResponse::Interface*>(interface)
      ->WithRequestWithResponse(std::move(message->arg), completer);
}

}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry WithAndWithoutRequestResponse[] = {
    {kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal,
     WithAndWithoutRequestResponse::NoRequestNoResponseRequest::Type,
     methods::WithAndWithoutRequestResponseDispatchNoRequestNoResponse},
    {kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal,
     WithAndWithoutRequestResponse::NoRequestEmptyResponseRequest::Type,
     methods::WithAndWithoutRequestResponseDispatchNoRequestEmptyResponse},
    {kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal,
     WithAndWithoutRequestResponse::NoRequestWithResponseRequest::Type,
     methods::WithAndWithoutRequestResponseDispatchNoRequestWithResponse},
    {kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal,
     WithAndWithoutRequestResponse::WithRequestNoResponseRequest::Type,
     methods::WithAndWithoutRequestResponseDispatchWithRequestNoResponse},
    {kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal,
     WithAndWithoutRequestResponse::WithRequestEmptyResponseRequest::Type,
     methods::WithAndWithoutRequestResponseDispatchWithRequestEmptyResponse},
    {kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
     WithAndWithoutRequestResponse::WithRequestWithResponseRequest::Type,
     methods::WithAndWithoutRequestResponseDispatchWithRequestWithResponse},
};

}  // namespace entries

::fidl::DispatchResult WithAndWithoutRequestResponse::TryDispatch(
    Interface* impl, fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries::WithAndWithoutRequestResponse,
      entries::WithAndWithoutRequestResponse +
          sizeof(entries::WithAndWithoutRequestResponse) /
              sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult WithAndWithoutRequestResponse::Dispatch(
    Interface* impl, fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  ::fidl::DispatchResult dispatch_result = TryDispatch(impl, msg, txn);
  if (dispatch_result == ::fidl::DispatchResult::kNotFound) {
    FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
    txn->InternalError(
        {::fidl::UnbindInfo::kUnexpectedMessage, ZX_ERR_NOT_SUPPORTED});
  }
  return dispatch_result;
}

::fidl::DispatchResult
WithAndWithoutRequestResponse::Interface::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return WithAndWithoutRequestResponse::Dispatch(this, msg, txn);
}

::fidl::Result WithAndWithoutRequestResponse::Interface::
    NoRequestEmptyResponseCompleterBase::Reply() {
  NoRequestEmptyResponseResponse::OwnedEncodedMessage _response{};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result WithAndWithoutRequestResponse::Interface::
    NoRequestWithResponseCompleterBase::Reply(::fidl::StringView ret) {
  NoRequestWithResponseResponse::OwnedEncodedMessage _response{ret};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result WithAndWithoutRequestResponse::Interface::
    NoRequestWithResponseCompleterBase::Reply(::fidl::BufferSpan _buffer,
                                              ::fidl::StringView ret) {
  NoRequestWithResponseResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, ret);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result WithAndWithoutRequestResponse::Interface::
    WithRequestEmptyResponseCompleterBase::Reply() {
  WithRequestEmptyResponseResponse::OwnedEncodedMessage _response{};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result WithAndWithoutRequestResponse::Interface::
    WithRequestWithResponseCompleterBase::Reply(::fidl::StringView ret) {
  WithRequestWithResponseResponse::OwnedEncodedMessage _response{ret};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result WithAndWithoutRequestResponse::Interface::
    WithRequestWithResponseCompleterBase::Reply(::fidl::BufferSpan _buffer,
                                                ::fidl::StringView ret) {
  WithRequestWithResponseResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, ret);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

void WithAndWithoutRequestResponse::NoRequestNoResponseRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid, kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal);
}

void WithAndWithoutRequestResponse::NoRequestEmptyResponseRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal);
}

void WithAndWithoutRequestResponse::NoRequestEmptyResponseResponse::
    _InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal);
}

void WithAndWithoutRequestResponse::NoRequestWithResponseRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal);
}

void WithAndWithoutRequestResponse::NoRequestWithResponseResponse::
    _InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal);
}

void WithAndWithoutRequestResponse::WithRequestNoResponseRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal);
}

void WithAndWithoutRequestResponse::WithRequestEmptyResponseRequest::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal);
}

void WithAndWithoutRequestResponse::WithRequestEmptyResponseResponse::
    _InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal);
}

void WithAndWithoutRequestResponse::WithRequestWithResponseRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal);
}

void WithAndWithoutRequestResponse::WithRequestWithResponseResponse::
    _InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal);
}

void WithAndWithoutRequestResponse::OnEmptyResponseResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal);
}

void WithAndWithoutRequestResponse::OnWithResponseResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       kWithAndWithoutRequestResponse_OnWithResponse_Ordinal);
}

zx_status_t WithAndWithoutRequestResponse::EventSender::OnEmptyResponse()
    const {
  OnEmptyResponseResponse::OwnedEncodedMessage _response{};
  _response.Write(server_end_.get());
  return _response.status();
}

zx_status_t WithAndWithoutRequestResponse::EventSender::OnWithResponse(
    ::fidl::StringView ret) const {
  OnWithResponseResponse::OwnedEncodedMessage _response{ret};
  _response.Write(server_end_.get());
  return _response.status();
}

zx_status_t WithAndWithoutRequestResponse::EventSender::OnWithResponse(
    ::fidl::BufferSpan _buffer, ::fidl::StringView ret) const {
  OnWithResponseResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, ret);
  _response.Write(server_end_.get());
  return _response.status();
}

void ::llcpp::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntax_ErrorAsEnum_Result) ==
                sizeof(fidl_xunion_t));
  static_assert(offsetof(WithErrorSyntax_ErrorAsEnum_Result, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(WithErrorSyntax_ErrorAsEnum_Result, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

namespace {

[[maybe_unused]] constexpr uint64_t kWithErrorSyntax_ResponseAsStruct_Ordinal =
    4000554951765344912lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructResponseTable;
[[maybe_unused]] constexpr uint64_t kWithErrorSyntax_ErrorAsPrimitive_Ordinal =
    3421672554503271630lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveResponseTable;
[[maybe_unused]] constexpr uint64_t kWithErrorSyntax_ErrorAsEnum_Ordinal =
    627496610701472780lu;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumResponseTable;

}  // namespace
WithErrorSyntax::ResultOf::ResponseAsStruct::ResponseAsStruct(
    zx_handle_t _client) {
  ResponseAsStructRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ResponseAsStructResponse>(
      _client, bytes_,
      ResponseAsStructResponse::PrimarySize +
          ResponseAsStructResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::ResultOf::ResponseAsStruct::ResponseAsStruct(
    zx_handle_t _client, zx_time_t _deadline) {
  ResponseAsStructRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ResponseAsStructResponse>(
      _client, bytes_,
      ResponseAsStructResponse::PrimarySize +
          ResponseAsStructResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::UnownedResultOf::ResponseAsStruct::ResponseAsStruct(
    zx_handle_t _client, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ResponseAsStructRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ResponseAsStructResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::ResultOf::ErrorAsPrimitive::ErrorAsPrimitive(
    zx_handle_t _client) {
  ErrorAsPrimitiveRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ErrorAsPrimitiveResponse>(
      _client, bytes_,
      ErrorAsPrimitiveResponse::PrimarySize +
          ErrorAsPrimitiveResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::ResultOf::ErrorAsPrimitive::ErrorAsPrimitive(
    zx_handle_t _client, zx_time_t _deadline) {
  ErrorAsPrimitiveRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ErrorAsPrimitiveResponse>(
      _client, bytes_,
      ErrorAsPrimitiveResponse::PrimarySize +
          ErrorAsPrimitiveResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::UnownedResultOf::ErrorAsPrimitive::ErrorAsPrimitive(
    zx_handle_t _client, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ErrorAsPrimitiveRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ErrorAsPrimitiveResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::ResultOf::ErrorAsEnum::ErrorAsEnum(zx_handle_t _client) {
  ErrorAsEnumRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ErrorAsEnumResponse>(
      _client, bytes_,
      ErrorAsEnumResponse::PrimarySize + ErrorAsEnumResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::ResultOf::ErrorAsEnum::ErrorAsEnum(zx_handle_t _client,
                                                    zx_time_t _deadline) {
  ErrorAsEnumRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ErrorAsEnumResponse>(
      _client, bytes_,
      ErrorAsEnumResponse::PrimarySize + ErrorAsEnumResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::UnownedResultOf::ErrorAsEnum::ErrorAsEnum(
    zx_handle_t _client, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ErrorAsEnumRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<ErrorAsEnumResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

WithErrorSyntax::ResultOf::ResponseAsStruct
WithErrorSyntax::ClientImpl::ResponseAsStruct_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::ResponseAsStruct(_channel->handle());
  }
  return WithErrorSyntax::ResultOf::ResponseAsStruct(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithErrorSyntax::UnownedResultOf::ResponseAsStruct
WithErrorSyntax::ClientImpl::ResponseAsStruct_Sync(
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::ResponseAsStruct(
        _channel->handle(), _response_buffer.data, _response_buffer.capacity);
  }
  return WithErrorSyntax::UnownedResultOf::ResponseAsStruct(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithErrorSyntax::ResponseAsStructResponseContext::
    ResponseAsStructResponseContext()
    : ::fidl::internal::ResponseContext(
          ResponseAsStructResponse::Type,
          kWithErrorSyntax_ResponseAsStruct_Ordinal) {}

void WithErrorSyntax::ResponseAsStructResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<ResponseAsStructResponse*>(reply));
}

::fidl::Result WithErrorSyntax::ClientImpl::ResponseAsStruct(
    ::fit::callback<void(ResponseAsStructResponse* response)> _cb) {
  class ResponseContext final : public ResponseAsStructResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(ResponseAsStructResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(ResponseAsStructResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(ResponseAsStructResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  ResponseAsStructRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result WithErrorSyntax::ClientImpl::ResponseAsStruct(
    ResponseAsStructResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ResponseAsStructRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

WithErrorSyntax::ResultOf::ErrorAsPrimitive
WithErrorSyntax::ClientImpl::ErrorAsPrimitive_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::ErrorAsPrimitive(_channel->handle());
  }
  return WithErrorSyntax::ResultOf::ErrorAsPrimitive(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithErrorSyntax::UnownedResultOf::ErrorAsPrimitive
WithErrorSyntax::ClientImpl::ErrorAsPrimitive_Sync(
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::ErrorAsPrimitive(
        _channel->handle(), _response_buffer.data, _response_buffer.capacity);
  }
  return WithErrorSyntax::UnownedResultOf::ErrorAsPrimitive(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithErrorSyntax::ErrorAsPrimitiveResponseContext::
    ErrorAsPrimitiveResponseContext()
    : ::fidl::internal::ResponseContext(
          ErrorAsPrimitiveResponse::Type,
          kWithErrorSyntax_ErrorAsPrimitive_Ordinal) {}

void WithErrorSyntax::ErrorAsPrimitiveResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<ErrorAsPrimitiveResponse*>(reply));
}

::fidl::Result WithErrorSyntax::ClientImpl::ErrorAsPrimitive(
    ::fit::callback<void(ErrorAsPrimitiveResponse* response)> _cb) {
  class ResponseContext final : public ErrorAsPrimitiveResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(ErrorAsPrimitiveResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(ErrorAsPrimitiveResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(ErrorAsPrimitiveResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  ErrorAsPrimitiveRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result WithErrorSyntax::ClientImpl::ErrorAsPrimitive(
    ErrorAsPrimitiveResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ErrorAsPrimitiveRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

WithErrorSyntax::ResultOf::ErrorAsEnum
WithErrorSyntax::ClientImpl::ErrorAsEnum_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::ErrorAsEnum(_channel->handle());
  }
  return WithErrorSyntax::ResultOf::ErrorAsEnum(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithErrorSyntax::UnownedResultOf::ErrorAsEnum
WithErrorSyntax::ClientImpl::ErrorAsEnum_Sync(
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::ErrorAsEnum(
        _channel->handle(), _response_buffer.data, _response_buffer.capacity);
  }
  return WithErrorSyntax::UnownedResultOf::ErrorAsEnum(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

WithErrorSyntax::ErrorAsEnumResponseContext::ErrorAsEnumResponseContext()
    : ::fidl::internal::ResponseContext(ErrorAsEnumResponse::Type,
                                        kWithErrorSyntax_ErrorAsEnum_Ordinal) {}

void WithErrorSyntax::ErrorAsEnumResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<ErrorAsEnumResponse*>(reply));
}

::fidl::Result WithErrorSyntax::ClientImpl::ErrorAsEnum(
    ::fit::callback<void(ErrorAsEnumResponse* response)> _cb) {
  class ResponseContext final : public ErrorAsEnumResponseContext {
   public:
    ResponseContext(::fit::callback<void(ErrorAsEnumResponse* response)> cb)
        : cb_(std::move(cb)) {}

    void OnReply(ErrorAsEnumResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(ErrorAsEnumResponse* response)> cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  ErrorAsEnumRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result WithErrorSyntax::ClientImpl::ErrorAsEnum(
    ErrorAsEnumResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ErrorAsEnumRequest::OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}

std::optional<::fidl::UnbindInfo> WithErrorSyntax::ClientImpl::DispatchEvent(
    fidl_incoming_msg_t* msg) {
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    default:
      FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
      return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                ZX_ERR_NOT_SUPPORTED};
  }
  return {};
}

namespace methods {

void WithErrorSyntaxDispatchResponseAsStruct(void* interface, void* bytes,
                                             ::fidl::Transaction* txn) {
  WithErrorSyntax::Interface::ResponseAsStructCompleter::Sync completer(txn);
  reinterpret_cast<WithErrorSyntax::Interface*>(interface)->ResponseAsStruct(
      completer);
}

void WithErrorSyntaxDispatchErrorAsPrimitive(void* interface, void* bytes,
                                             ::fidl::Transaction* txn) {
  WithErrorSyntax::Interface::ErrorAsPrimitiveCompleter::Sync completer(txn);
  reinterpret_cast<WithErrorSyntax::Interface*>(interface)->ErrorAsPrimitive(
      completer);
}

void WithErrorSyntaxDispatchErrorAsEnum(void* interface, void* bytes,
                                        ::fidl::Transaction* txn) {
  WithErrorSyntax::Interface::ErrorAsEnumCompleter::Sync completer(txn);
  reinterpret_cast<WithErrorSyntax::Interface*>(interface)->ErrorAsEnum(
      completer);
}

}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry WithErrorSyntax[] = {
    {kWithErrorSyntax_ResponseAsStruct_Ordinal,
     WithErrorSyntax::ResponseAsStructRequest::Type,
     methods::WithErrorSyntaxDispatchResponseAsStruct},
    {kWithErrorSyntax_ErrorAsPrimitive_Ordinal,
     WithErrorSyntax::ErrorAsPrimitiveRequest::Type,
     methods::WithErrorSyntaxDispatchErrorAsPrimitive},
    {kWithErrorSyntax_ErrorAsEnum_Ordinal,
     WithErrorSyntax::ErrorAsEnumRequest::Type,
     methods::WithErrorSyntaxDispatchErrorAsEnum},
};

}  // namespace entries

::fidl::DispatchResult WithErrorSyntax::TryDispatch(Interface* impl,
                                                    fidl_incoming_msg_t* msg,
                                                    ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries::WithErrorSyntax,
      entries::WithErrorSyntax + sizeof(entries::WithErrorSyntax) /
                                     sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult WithErrorSyntax::Dispatch(Interface* impl,
                                                 fidl_incoming_msg_t* msg,
                                                 ::fidl::Transaction* txn) {
  ::fidl::DispatchResult dispatch_result = TryDispatch(impl, msg, txn);
  if (dispatch_result == ::fidl::DispatchResult::kNotFound) {
    FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
    txn->InternalError(
        {::fidl::UnbindInfo::kUnexpectedMessage, ZX_ERR_NOT_SUPPORTED});
  }
  return dispatch_result;
}

::fidl::DispatchResult WithErrorSyntax::Interface::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return WithErrorSyntax::Dispatch(this, msg, txn);
}

::fidl::Result WithErrorSyntax::Interface::ResponseAsStructCompleterBase::Reply(
    ::llcpp::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result
        result) {
  ResponseAsStructResponse::OwnedEncodedMessage _response{result};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
::fidl::Result
WithErrorSyntax::Interface::ResponseAsStructCompleterBase::ReplySuccess(
    int64_t a, int64_t b, int64_t c) {
  ::fidl::aligned<WithErrorSyntax_ResponseAsStruct_Response> _response;
  _response.value.a = std::move(a);
  _response.value.b = std::move(b);
  _response.value.c = std::move(c);

  return Reply(WithErrorSyntax_ResponseAsStruct_Result::WithResponse(
      ::fidl::unowned_ptr(&_response)));
}
::fidl::Result
WithErrorSyntax::Interface::ResponseAsStructCompleterBase::ReplyError(
    uint32_t error) {
  return Reply(WithErrorSyntax_ResponseAsStruct_Result::WithErr(
      ::fidl::unowned_ptr(&error)));
}

::fidl::Result WithErrorSyntax::Interface::ResponseAsStructCompleterBase::Reply(
    ::fidl::BufferSpan _buffer,
    ::llcpp::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result
        result) {
  ResponseAsStructResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
::fidl::Result
WithErrorSyntax::Interface::ResponseAsStructCompleterBase::ReplySuccess(
    ::fidl::BufferSpan _buffer, int64_t a, int64_t b, int64_t c) {
  ::fidl::aligned<WithErrorSyntax_ResponseAsStruct_Response> response;
  response.value.a = std::move(a);
  response.value.b = std::move(b);
  response.value.c = std::move(c);

  return Reply(std::move(_buffer),
               WithErrorSyntax_ResponseAsStruct_Result::WithResponse(
                   ::fidl::unowned_ptr(&response)));
}

::fidl::Result WithErrorSyntax::Interface::ErrorAsPrimitiveCompleterBase::Reply(
    ::llcpp::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result
        result) {
  ErrorAsPrimitiveResponse::OwnedEncodedMessage _response{result};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
::fidl::Result
WithErrorSyntax::Interface::ErrorAsPrimitiveCompleterBase::ReplySuccess() {
  ::fidl::aligned<WithErrorSyntax_ErrorAsPrimitive_Response> _response;

  return Reply(WithErrorSyntax_ErrorAsPrimitive_Result::WithResponse(
      ::fidl::unowned_ptr(&_response)));
}
::fidl::Result
WithErrorSyntax::Interface::ErrorAsPrimitiveCompleterBase::ReplyError(
    uint32_t error) {
  return Reply(WithErrorSyntax_ErrorAsPrimitive_Result::WithErr(
      ::fidl::unowned_ptr(&error)));
}

::fidl::Result WithErrorSyntax::Interface::ErrorAsPrimitiveCompleterBase::Reply(
    ::fidl::BufferSpan _buffer,
    ::llcpp::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result
        result) {
  ErrorAsPrimitiveResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
::fidl::Result
WithErrorSyntax::Interface::ErrorAsPrimitiveCompleterBase::ReplySuccess(
    ::fidl::BufferSpan _buffer) {
  ::fidl::aligned<WithErrorSyntax_ErrorAsPrimitive_Response> response;

  return Reply(std::move(_buffer),
               WithErrorSyntax_ErrorAsPrimitive_Result::WithResponse(
                   ::fidl::unowned_ptr(&response)));
}

::fidl::Result WithErrorSyntax::Interface::ErrorAsEnumCompleterBase::Reply(
    ::llcpp::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result result) {
  ErrorAsEnumResponse::OwnedEncodedMessage _response{result};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
::fidl::Result
WithErrorSyntax::Interface::ErrorAsEnumCompleterBase::ReplySuccess() {
  ::fidl::aligned<WithErrorSyntax_ErrorAsEnum_Response> _response;

  return Reply(WithErrorSyntax_ErrorAsEnum_Result::WithResponse(
      ::fidl::unowned_ptr(&_response)));
}
::fidl::Result WithErrorSyntax::Interface::ErrorAsEnumCompleterBase::ReplyError(
    ErrorEnun error) {
  return Reply(
      WithErrorSyntax_ErrorAsEnum_Result::WithErr(::fidl::unowned_ptr(&error)));
}

::fidl::Result WithErrorSyntax::Interface::ErrorAsEnumCompleterBase::Reply(
    ::fidl::BufferSpan _buffer,
    ::llcpp::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result result) {
  ErrorAsEnumResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
::fidl::Result
WithErrorSyntax::Interface::ErrorAsEnumCompleterBase::ReplySuccess(
    ::fidl::BufferSpan _buffer) {
  ::fidl::aligned<WithErrorSyntax_ErrorAsEnum_Response> response;

  return Reply(std::move(_buffer),
               WithErrorSyntax_ErrorAsEnum_Result::WithResponse(
                   ::fidl::unowned_ptr(&response)));
}

void WithErrorSyntax::ResponseAsStructRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kWithErrorSyntax_ResponseAsStruct_Ordinal);
}

void WithErrorSyntax::ResponseAsStructResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kWithErrorSyntax_ResponseAsStruct_Ordinal);
}

void WithErrorSyntax::ErrorAsPrimitiveRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kWithErrorSyntax_ErrorAsPrimitive_Ordinal);
}

void WithErrorSyntax::ErrorAsPrimitiveResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kWithErrorSyntax_ErrorAsPrimitive_Ordinal);
}

void WithErrorSyntax::ErrorAsEnumRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kWithErrorSyntax_ErrorAsEnum_Ordinal);
}

void WithErrorSyntax::ErrorAsEnumResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kWithErrorSyntax_ErrorAsEnum_Ordinal);
}

}  // namespace protocols
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
