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

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

#include <memory>

namespace llcpp {

namespace fidl {
namespace test {
namespace protocolrequest {

namespace {

[[maybe_unused]] constexpr uint64_t kParent_GetChild_Ordinal =
    7929845654914578302lu;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildResponseTable;
[[maybe_unused]] constexpr uint64_t kParent_GetChildRequest_Ordinal =
    1819029190665166744lu;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildRequestRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildRequestResponseTable;
[[maybe_unused]] constexpr uint64_t kParent_TakeChild_Ordinal =
    374110854839013230lu;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentTakeChildRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentTakeChildResponseTable;
[[maybe_unused]] constexpr uint64_t kParent_TakeChildRequest_Ordinal =
    1574820689302890956lu;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentTakeChildRequestRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentTakeChildRequestResponseTable;

}  // namespace
Parent::ResultOf::GetChild::GetChild(zx_handle_t _client) {
  GetChildRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<GetChildResponse>(
      _client, bytes_,
      GetChildResponse::PrimarySize + GetChildResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::ResultOf::GetChild::GetChild(zx_handle_t _client, zx_time_t _deadline) {
  GetChildRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<GetChildResponse>(
      _client, bytes_,
      GetChildResponse::PrimarySize + GetChildResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::UnownedResultOf::GetChild::GetChild(zx_handle_t _client,
                                            uint8_t* _response_bytes,
                                            uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  GetChildRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<GetChildResponse>(_client, _response_bytes,
                                                       _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::ResultOf::GetChildRequest::GetChildRequest(zx_handle_t _client) {
  GetChildRequestRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<GetChildRequestResponse>(
      _client, bytes_,
      GetChildRequestResponse::PrimarySize +
          GetChildRequestResponse::MaxOutOfLine);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::ResultOf::GetChildRequest::GetChildRequest(zx_handle_t _client,
                                                   zx_time_t _deadline) {
  GetChildRequestRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<GetChildRequestResponse>(
      _client, bytes_,
      GetChildRequestResponse::PrimarySize +
          GetChildRequestResponse::MaxOutOfLine,
      _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::UnownedResultOf::GetChildRequest::GetChildRequest(
    zx_handle_t _client, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  GetChildRequestRequest::OwnedEncodedMessage _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Call<GetChildRequestResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::ResultOf::TakeChild::TakeChild(zx_handle_t _client, ::zx::channel& c) {
  TakeChildRequest::OwnedEncodedMessage _request(zx_txid_t(0), c);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::UnownedResultOf::TakeChild::TakeChild(zx_handle_t _client,
                                              uint8_t* _request_bytes,
                                              uint32_t _request_byte_capacity,
                                              ::zx::channel& c) {
  TakeChildRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, c);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::ResultOf::TakeChildRequest::TakeChildRequest(zx_handle_t _client,
                                                     ::zx::channel& r) {
  TakeChildRequestRequest::OwnedEncodedMessage _request(zx_txid_t(0), r);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

Parent::UnownedResultOf::TakeChildRequest::TakeChildRequest(
    zx_handle_t _client, uint8_t* _request_bytes,
    uint32_t _request_byte_capacity, ::zx::channel& r) {
  TakeChildRequestRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, r);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}

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

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

Parent::GetChildResponseContext::GetChildResponseContext()
    : ::fidl::internal::ResponseContext(GetChildResponse::Type,
                                        kParent_GetChild_Ordinal) {}

void Parent::GetChildResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<GetChildResponse*>(reply));
}

::fidl::Result Parent::ClientImpl::GetChild(
    ::fit::callback<void(GetChildResponse* response)> _cb) {
  class ResponseContext final : public GetChildResponseContext {
   public:
    ResponseContext(::fit::callback<void(GetChildResponse* response)> cb)
        : cb_(std::move(cb)) {}

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

      response->_CloseHandles();

      delete this;
    }

    void OnError() override { delete this; }

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

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

::fidl::Result Parent::ClientImpl::GetChild(GetChildResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

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

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

Parent::GetChildRequestResponseContext::GetChildRequestResponseContext()
    : ::fidl::internal::ResponseContext(GetChildRequestResponse::Type,
                                        kParent_GetChildRequest_Ordinal) {}

void Parent::GetChildRequestResponseContext::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<GetChildRequestResponse*>(reply));
}

::fidl::Result Parent::ClientImpl::GetChildRequest(
    ::fit::callback<void(GetChildRequestResponse* response)> _cb) {
  class ResponseContext final : public GetChildRequestResponseContext {
   public:
    ResponseContext(::fit::callback<void(GetChildRequestResponse* response)> cb)
        : cb_(std::move(cb)) {}

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

      response->_CloseHandles();

      delete this;
    }

    void OnError() override { delete this; }

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

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

::fidl::Result Parent::ClientImpl::GetChildRequest(
    GetChildRequestResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

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

::fidl::Result Parent::ClientImpl::TakeChild(::fidl::BufferSpan _request_buffer,
                                             ::zx::channel c) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = UnownedResultOf::TakeChild(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, c);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

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

::fidl::Result Parent::ClientImpl::TakeChildRequest(
    ::fidl::BufferSpan _request_buffer, ::zx::channel r) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = UnownedResultOf::TakeChildRequest(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, r);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}

std::optional<::fidl::UnbindInfo> Parent::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 ParentDispatchGetChild(void* interface, void* bytes,
                            ::fidl::Transaction* txn) {
  Parent::Interface::GetChildCompleter::Sync completer(txn);
  reinterpret_cast<Parent::Interface*>(interface)->GetChild(completer);
}

void ParentDispatchGetChildRequest(void* interface, void* bytes,
                                   ::fidl::Transaction* txn) {
  Parent::Interface::GetChildRequestCompleter::Sync completer(txn);
  reinterpret_cast<Parent::Interface*>(interface)->GetChildRequest(completer);
}

void ParentDispatchTakeChild(void* interface, void* bytes,
                             ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<Parent::TakeChildRequest*>(bytes);
  Parent::Interface::TakeChildCompleter::Sync completer(txn);
  reinterpret_cast<Parent::Interface*>(interface)->TakeChild(
      std::move(message->c), completer);
}

void ParentDispatchTakeChildRequest(void* interface, void* bytes,
                                    ::fidl::Transaction* txn) {
  auto message = reinterpret_cast<Parent::TakeChildRequestRequest*>(bytes);
  Parent::Interface::TakeChildRequestCompleter::Sync completer(txn);
  reinterpret_cast<Parent::Interface*>(interface)->TakeChildRequest(
      std::move(message->r), completer);
}

}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry Parent[] = {
    {kParent_GetChild_Ordinal, Parent::GetChildRequest::Type,
     methods::ParentDispatchGetChild},
    {kParent_GetChildRequest_Ordinal, Parent::GetChildRequestRequest::Type,
     methods::ParentDispatchGetChildRequest},
    {kParent_TakeChild_Ordinal, Parent::TakeChildRequest::Type,
     methods::ParentDispatchTakeChild},
    {kParent_TakeChildRequest_Ordinal, Parent::TakeChildRequestRequest::Type,
     methods::ParentDispatchTakeChildRequest},
};

}  // namespace entries

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

::fidl::DispatchResult Parent::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 Parent::Interface::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return Parent::Dispatch(this, msg, txn);
}

::fidl::Result Parent::Interface::GetChildCompleterBase::Reply(
    ::zx::channel c) {
  GetChildResponse::OwnedEncodedMessage _response{c};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result Parent::Interface::GetChildCompleterBase::Reply(
    ::fidl::BufferSpan _buffer, ::zx::channel c) {
  GetChildResponse::UnownedEncodedMessage _response(_buffer.data,
                                                    _buffer.capacity, c);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result Parent::Interface::GetChildRequestCompleterBase::Reply(
    ::zx::channel r) {
  GetChildRequestResponse::OwnedEncodedMessage _response{r};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result Parent::Interface::GetChildRequestCompleterBase::Reply(
    ::fidl::BufferSpan _buffer, ::zx::channel r) {
  GetChildRequestResponse::UnownedEncodedMessage _response(_buffer.data,
                                                           _buffer.capacity, r);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

void Parent::GetChildRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kParent_GetChild_Ordinal);
}

void Parent::GetChildResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kParent_GetChild_Ordinal);
}

void Parent::GetChildResponse::_CloseHandles() { c.reset(); }

void Parent::GetChildRequestRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kParent_GetChildRequest_Ordinal);
}

void Parent::GetChildRequestResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, kParent_GetChildRequest_Ordinal);
}

void Parent::GetChildRequestResponse::_CloseHandles() { r.reset(); }

void Parent::TakeChildRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kParent_TakeChild_Ordinal);
}

void Parent::TakeChildRequest::_CloseHandles() { c.reset(); }

void Parent::TakeChildRequestRequest::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, kParent_TakeChildRequest_Ordinal);
}

void Parent::TakeChildRequestRequest::_CloseHandles() { r.reset(); }

namespace {}  // namespace

std::optional<::fidl::UnbindInfo> Child::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 {}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry Child[] = {};

}  // namespace entries

::fidl::DispatchResult Child::TryDispatch(Interface* impl,
                                          fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) {
  return ::fidl::DispatchResult::kNotFound;
}

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

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

}  // namespace protocolrequest
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
