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

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

#include <memory>

namespace fidl_test_protocolrequest {
[[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;
#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChild>::WireResult(
    ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChild>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<
          ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChild>::WireResult(
    ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
    zx_time_t _deadline) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChild>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<
          ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>>(
          _client, bytes_.data(), bytes_.size(), _deadline);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireUnownedResult<::fidl_test_protocolrequest::Parent::GetChild>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChild>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<
          ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChildRequest>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChildRequest>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocolrequest::Parent::GetChildRequest>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChildRequest>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
        zx_time_t _deadline) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChildRequest>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocolrequest::Parent::GetChildRequest>>(
          _client, bytes_.data(), bytes_.size(), _deadline);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireUnownedResult<
    ::fidl_test_protocolrequest::Parent::GetChildRequest>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChildRequest>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocolrequest::Parent::GetChildRequest>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireResult<::fidl_test_protocolrequest::Parent::TakeChild>::WireResult(
    ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
    ::fidl::ClientEnd<::fidl_test_protocolrequest::Child>&& c) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::TakeChild>>
      _request(zx_txid_t(0), std::move(c));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireUnownedResult<::fidl_test_protocolrequest::Parent::TakeChild>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity,
        ::fidl::ClientEnd<::fidl_test_protocolrequest::Child>&& c) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::TakeChild>>
      _request(_request_bytes, _request_byte_capacity, 0, std::move(c));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireResult<::fidl_test_protocolrequest::Parent::TakeChildRequest>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
        ::fidl::ServerEnd<::fidl_test_protocolrequest::Child>&& r) {
  ::fidl::OwnedEncodedMessage<::fidl::WireRequest<
      ::fidl_test_protocolrequest::Parent::TakeChildRequest>>
      _request(zx_txid_t(0), std::move(r));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocolrequest
::fidl::WireUnownedResult<
    ::fidl_test_protocolrequest::Parent::TakeChildRequest>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent> _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity,
        ::fidl::ServerEnd<::fidl_test_protocolrequest::Child>&& r) {
  ::fidl::UnownedEncodedMessage<::fidl::WireRequest<
      ::fidl_test_protocolrequest::Parent::TakeChildRequest>>
      _request(_request_bytes, _request_byte_capacity, 0, std::move(r));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocolrequest {
#endif  // __Fuchsia__

}  // namespace fidl_test_protocolrequest
#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChild>
fidl::internal::WireClientImpl<
    ::fidl_test_protocolrequest::Parent>::GetChild_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChild>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()));
  }
  return ::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChild>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocolrequest::Parent::GetChild>
fidl::internal::WireClientImpl<::fidl_test_protocolrequest::Parent>::
    GetChild_Sync(::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocolrequest::Parent::GetChild>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()),
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocolrequest::Parent::GetChild>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocolrequest::Parent::GetChild>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocolrequest::Parent::GetChild>::Type,
          ::fidl_test_protocolrequest::kParent_GetChild_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocolrequest::Parent::GetChild>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>*>(
      reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocolrequest::Parent>::GetChild(
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>*
            response)>
        _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_protocolrequest::Parent::GetChild> {
   public:
    ResponseContext(
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>*
                response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(
        ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>*
            response) override {
      cb_(response);

      response->_CloseHandles();

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>*
            response)>
        cb_;
  };

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

::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocolrequest::Parent>::GetChild(
    ::fidl::WireResponseContext<::fidl_test_protocolrequest::Parent::GetChild>*
        _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChild>::
      OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocolrequest::Parent::GetChildRequest>
fidl::internal::WireClientImpl<
    ::fidl_test_protocolrequest::Parent>::GetChildRequest_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocolrequest::Parent::GetChildRequest>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()));
  }
  return ::fidl::WireResult<
      ::fidl_test_protocolrequest::Parent::GetChildRequest>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocolrequest::Parent::GetChildRequest>
fidl::internal::WireClientImpl<::fidl_test_protocolrequest::Parent>::
    GetChildRequest_Sync(::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocolrequest::Parent::GetChildRequest>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()),
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocolrequest::Parent::GetChildRequest>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocolrequest::Parent::GetChildRequest>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocolrequest::Parent::GetChildRequest>::Type,
          ::fidl_test_protocolrequest::kParent_GetChildRequest_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocolrequest::Parent::GetChildRequest>::OnReply(uint8_t*
                                                                       reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocolrequest::Parent::GetChildRequest>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocolrequest::Parent>::GetChildRequest(
        ::fit::callback<
            void(::fidl::WireResponse<::fidl_test_protocolrequest::Parent::
                                          GetChildRequest>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_protocolrequest::Parent::GetChildRequest> {
   public:
    ResponseContext(::fit::callback<
                    void(::fidl::WireResponse<
                         ::fidl_test_protocolrequest::Parent::GetChildRequest>*
                             response)>
                        cb)
        : cb_(std::move(cb)) {}

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocolrequest::Parent::GetChildRequest>*
                     response) override {
      cb_(response);

      response->_CloseHandles();

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<
            ::fidl_test_protocolrequest::Parent::GetChildRequest>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocolrequest::Parent>::GetChildRequest(
        ::fidl::WireResponseContext<
            ::fidl_test_protocolrequest::Parent::GetChildRequest>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChildRequest>::
      OwnedEncodedMessage _request(_context->Txid());
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocolrequest::Parent>::TakeChild(
    ::fidl::ClientEnd<::fidl_test_protocolrequest::Child>&& c) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res =
        ::fidl::WireResult<::fidl_test_protocolrequest::Parent::TakeChild>(
            ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
                _channel->handle()),
            std::move(c));
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocolrequest::Parent>::TakeChild(
    ::fidl::BufferSpan _request_buffer,
    ::fidl::ClientEnd<::fidl_test_protocolrequest::Child>&& c) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_protocolrequest::Parent::TakeChild>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(c));
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocolrequest::Parent>::TakeChildRequest(
        ::fidl::ServerEnd<::fidl_test_protocolrequest::Child>&& r) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_protocolrequest::Parent::TakeChildRequest>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()),
        std::move(r));
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocolrequest::Parent>::TakeChildRequest(
        ::fidl::BufferSpan _request_buffer,
        ::fidl::ServerEnd<::fidl_test_protocolrequest::Child>&& r) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_protocolrequest::Parent::TakeChildRequest>(
        ::fidl::UnownedClientEnd<::fidl_test_protocolrequest::Parent>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(r));
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_protocolrequest::Parent>::DispatchEvent(fidl_incoming_msg_t*
                                                            msg) {
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                            ZX_ERR_NOT_SUPPORTED};
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_protocolrequest::Parent>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocolrequest::kParent_GetChild_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocolrequest::Parent::GetChild>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
                GetChildCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>*>(
                interface)
                ->GetChild(completer);
          },
      },
      {
          ::fidl_test_protocolrequest::kParent_GetChildRequest_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocolrequest::Parent::GetChildRequest>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
                GetChildRequestCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>*>(
                interface)
                ->GetChildRequest(completer);
          },
      },
      {
          ::fidl_test_protocolrequest::kParent_TakeChild_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocolrequest::Parent::TakeChild>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocolrequest::Parent::TakeChild>*>(bytes);
            ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
                TakeChildCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>*>(
                interface)
                ->TakeChild(std::move(message->c), completer);
          },
      },
      {
          ::fidl_test_protocolrequest::kParent_TakeChildRequest_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocolrequest::Parent::TakeChildRequest>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocolrequest::Parent::TakeChildRequest>*>(bytes);
            ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
                TakeChildRequestCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>*>(
                interface)
                ->TakeChildRequest(std::move(message->r), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult
fidl::internal::WireDispatcher<::fidl_test_protocolrequest::Parent>::Dispatch(
    ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>* 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
fidl::WireInterface<::fidl_test_protocolrequest::Parent>::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireDispatcher<
      ::fidl_test_protocolrequest::Parent>::Dispatch(this, msg, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
    GetChildCompleterBase::Reply(
        ::fidl::ClientEnd<::fidl_test_protocolrequest::Child>&& c) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>>
      _response{std::move(c)};
  return ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
      GetChildCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
    GetChildCompleterBase::Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl::ClientEnd<::fidl_test_protocolrequest::Child>&& c) {
  ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChild>::
      UnownedEncodedMessage _response(_buffer.data, _buffer.capacity,
                                      std::move(c));
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
    GetChildRequestCompleterBase::Reply(
        ::fidl::ServerEnd<::fidl_test_protocolrequest::Child>&& r) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocolrequest::Parent::GetChildRequest>>
      _response{std::move(r)};
  return ::fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
      GetChildRequestCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<::fidl_test_protocolrequest::Parent>::
    GetChildRequestCompleterBase::Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl::ServerEnd<::fidl_test_protocolrequest::Child>&& r) {
  ::fidl::WireResponse<::fidl_test_protocolrequest::Parent::GetChildRequest>::
      UnownedEncodedMessage _response(_buffer.data, _buffer.capacity,
                                      std::move(r));
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChild>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_protocolrequest::kParent_GetChild_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocolrequest::Parent::GetChild>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_protocolrequest::kParent_GetChild_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocolrequest::Parent::GetChild>::_CloseHandles() {
  c.reset();
}

void ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::GetChildRequest>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocolrequest::kParent_GetChildRequest_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocolrequest::Parent::GetChildRequest>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, ::fidl_test_protocolrequest::kParent_GetChildRequest_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocolrequest::Parent::GetChildRequest>::_CloseHandles() {
  r.reset();
}

void ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::TakeChild>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_protocolrequest::kParent_TakeChild_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_protocolrequest::Parent::TakeChild>::_CloseHandles() {
  c.reset();
}

void ::fidl::WireRequest<::fidl_test_protocolrequest::Parent::
                             TakeChildRequest>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocolrequest::kParent_TakeChildRequest_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_protocolrequest::Parent::TakeChildRequest>::_CloseHandles() {
  r.reset();
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_protocolrequest::Child>::DispatchEvent(fidl_incoming_msg_t*
                                                           msg) {
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                            ZX_ERR_NOT_SUPPORTED};
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::DispatchResult
fidl::internal::WireDispatcher<::fidl_test_protocolrequest::Child>::TryDispatch(
    ::fidl::WireInterface<::fidl_test_protocolrequest::Child>* impl,
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::DispatchResult::kNotFound;
}

::fidl::DispatchResult
fidl::internal::WireDispatcher<::fidl_test_protocolrequest::Child>::Dispatch(
    ::fidl::WireInterface<::fidl_test_protocolrequest::Child>* 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
fidl::WireInterface<::fidl_test_protocolrequest::Child>::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireDispatcher<
      ::fidl_test_protocolrequest::Child>::Dispatch(this, msg, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
