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

#include <fidl/test.protocolrequest/cpp/wire_messaging.h>

#include <memory>

namespace test_protocolrequest {
[[maybe_unused]] constexpr uint64_t kParent_GetChild_Ordinal = 881818649151440699lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags kParent_GetChild_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolrequest_ParentGetChildTopResponseTable;

[[maybe_unused]] constexpr uint64_t kParent_GetChildRequest_Ordinal = 1096855814967598201lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags kParent_GetChildRequest_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolrequest_ParentGetChildRequestTopResponseTable;

[[maybe_unused]] constexpr uint64_t kParent_TakeChild_Ordinal = 4470101341872267920lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags kParent_TakeChild_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolrequest_ParentTakeChildRequestTable;

[[maybe_unused]] constexpr uint64_t kParent_TakeChildRequest_Ordinal = 2333981071306416007lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags kParent_TakeChildRequest_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

extern "C" const fidl_type_t test_protocolrequest_ParentTakeChildRequestRequestTable;
#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireResult<::test_protocolrequest::Parent::GetChild>::WireResult(
    ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
    ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild>* request, std::optional<zx::time> deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>> handle_storage;
  ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>> decoded{
      outgoing.Call(
          client.handle(), handle_storage.view(bytes_.view()),
          deadline.has_value() ? fidl::CallOptions{.deadline = deadline->get()} : fidl::CallOptions{})};
  SetStatus(decoded);
  if (ok()) {
    decoded_ = decoded.Take();
  }
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireUnownedResult<::test_protocolrequest::Parent::GetChild>::WireUnownedResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::GetChild>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    SetStatus(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild>, ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>> handle_storage;
  ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>> decoded{
      outgoing.Call(
          client_end.handle(),
          handle_storage.view(fidl::BufferSpan(response_bytes, response_byte_capacity)))};
  SetStatus(decoded);
  if (ok()) {
    decoded_ = decoded.Take();
  }
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireResult<::test_protocolrequest::Parent::GetChildRequest>::WireResult(
    ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
    ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest>* request, std::optional<zx::time> deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>> handle_storage;
  ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>> decoded{
      outgoing.Call(
          client.handle(), handle_storage.view(bytes_.view()),
          deadline.has_value() ? fidl::CallOptions{.deadline = deadline->get()} : fidl::CallOptions{})};
  SetStatus(decoded);
  if (ok()) {
    decoded_ = decoded.Take();
  }
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireUnownedResult<::test_protocolrequest::Parent::GetChildRequest>::WireUnownedResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::GetChildRequest>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    SetStatus(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest>, ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];

  ::fidl::unstable::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>> handle_storage;
  ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>> decoded{
      outgoing.Call(
          client_end.handle(),
          handle_storage.view(fidl::BufferSpan(response_bytes, response_byte_capacity)))};
  SetStatus(decoded);
  if (ok()) {
    decoded_ = decoded.Take();
  }
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireResult<::test_protocolrequest::Parent::TakeChild>::WireResult(
    ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
    ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireUnownedResult<::test_protocolrequest::Parent::TakeChild>::WireUnownedResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::TakeChild>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    SetStatus(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  SetStatus(outgoing);
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireResult<::test_protocolrequest::Parent::TakeChildRequest>::WireResult(
    ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
    ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_protocolrequest
::fidl::WireUnownedResult<::test_protocolrequest::Parent::TakeChildRequest>::WireUnownedResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::TakeChildRequest>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    SetStatus(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  SetStatus(outgoing);
}
namespace test_protocolrequest {
#endif  // __Fuchsia__

}  // namespace test_protocolrequest
#ifdef __Fuchsia__

::fidl::Status fidl::internal::WireWeakOnewayClientImpl<::test_protocolrequest::Parent>::TakeChild(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild> _request_object{std::move(c)};
  ::fidl::unstable::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>, ::fidl::internal::ChannelTransport> _request_message(
      ::fidl::internal::AllowUnownedInputRef{}, &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayClientImpl<::test_protocolrequest::Parent>::TakeChildRequest(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest> _request_object{std::move(r)};
  ::fidl::unstable::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>, ::fidl::internal::ChannelTransport> _request_message(
      ::fidl::internal::AllowUnownedInputRef{}, &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}

::fidl::internal::WireThenable<::test_protocolrequest::Parent::GetChild> fidl::internal::WireWeakAsyncClientImpl<::test_protocolrequest::Parent>::GetChild() {
  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild> _request{};
  return ::fidl::internal::WireThenable<::test_protocolrequest::Parent::GetChild>{
      _client_base(), ::fidl::WriteOptions{}, ::fidl::internal::AllowUnownedInputRef{}, &_request};
}

::fidl::internal::WireThenable<::test_protocolrequest::Parent::GetChildRequest> fidl::internal::WireWeakAsyncClientImpl<::test_protocolrequest::Parent>::GetChildRequest() {
  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest> _request{};
  return ::fidl::internal::WireThenable<::test_protocolrequest::Parent::GetChildRequest>{
      _client_base(), ::fidl::WriteOptions{}, ::fidl::internal::AllowUnownedInputRef{}, &_request};
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<::test_protocolrequest::Parent>::TakeChild(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::TakeChild>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild> _request{std::move(c)};
  ::fidl::unstable::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>> _request_message(
      _allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<::test_protocolrequest::Parent>::TakeChildRequest(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::TakeChildRequest>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest> _request{std::move(r)};
  ::fidl::unstable::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>> _request_message(
      _allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::internal::WireBufferThenable<::test_protocolrequest::Parent::GetChild> fidl::internal::WireWeakAsyncBufferClientImpl<::test_protocolrequest::Parent>::GetChild() {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::GetChild>();
  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild> _request{};
  return ::fidl::internal::WireBufferThenable<::test_protocolrequest::Parent::GetChild>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size, &_request};
}
::fidl::internal::WireBufferThenable<::test_protocolrequest::Parent::GetChildRequest> fidl::internal::WireWeakAsyncBufferClientImpl<::test_protocolrequest::Parent>::GetChildRequest() {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_protocolrequest::Parent::GetChildRequest>();
  ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest> _request{};
  return ::fidl::internal::WireBufferThenable<::test_protocolrequest::Parent::GetChildRequest>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size, &_request};
}

::fidl::WireResult<::test_protocolrequest::Parent::GetChild>
fidl::internal::WireWeakSyncClientImpl<::test_protocolrequest::Parent>::GetChild() {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild> _request{};
        return ::fidl::WireResult<::test_protocolrequest::Parent::GetChild>(::fidl::UnownedClientEnd<::test_protocolrequest::Parent>(_transport->get<::fidl::internal::ChannelTransport>()), &_request);
      });
}

::fidl::WireResult<::test_protocolrequest::Parent::GetChildRequest>
fidl::internal::WireWeakSyncClientImpl<::test_protocolrequest::Parent>::GetChildRequest() {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest> _request{};
        return ::fidl::WireResult<::test_protocolrequest::Parent::GetChildRequest>(::fidl::UnownedClientEnd<::test_protocolrequest::Parent>(_transport->get<::fidl::internal::ChannelTransport>()), &_request);
      });
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::WireSyncEventHandler<::test_protocolrequest::Parent>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_protocolrequest::Parent> event_storage;
  fidl::internal::WireEventDispatcher<::test_protocolrequest::Parent> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::WireServerDispatcher<::test_protocolrequest::Parent>::entries_[] = {
    {
        ::test_protocolrequest::kParent_GetChild_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fidl::WireRequest<::test_protocolrequest::Parent::GetChild> empty_request;
          auto* primary = &empty_request;
          ::fidl::internal::WireCompleter<::test_protocolrequest::Parent::GetChild>::Sync completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_protocolrequest::Parent>*>(interface)->GetChild(
              primary, completer);
          return ::fidl::Status::Ok();
        },
    },
    {
        ::test_protocolrequest::kParent_GetChildRequest_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fidl::WireRequest<::test_protocolrequest::Parent::GetChildRequest> empty_request;
          auto* primary = &empty_request;
          ::fidl::internal::WireCompleter<::test_protocolrequest::Parent::GetChildRequest>::Sync completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_protocolrequest::Parent>*>(interface)->GetChildRequest(
              primary, completer);
          return ::fidl::Status::Ok();
        },
    },
    {
        ::test_protocolrequest::kParent_TakeChild_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>> decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return ::fidl::Status{decoded};
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<::test_protocolrequest::Parent::TakeChild>::Sync completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_protocolrequest::Parent>*>(interface)->TakeChild(
              primary, completer);
          return ::fidl::Status::Ok();
        },
    },
    {
        ::test_protocolrequest::kParent_TakeChildRequest_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>> decoded{std::move(msg)};
          if (unlikely(!decoded.ok())) {
            return ::fidl::Status{decoded};
          }
          auto* primary = &decoded.PrimaryObject()->body;
          ::fidl::internal::WireCompleter<::test_protocolrequest::Parent::TakeChildRequest>::Sync completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_protocolrequest::Parent>*>(interface)->TakeChildRequest(
              primary, completer);
          return ::fidl::Status::Ok();
        },
    },
};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<::test_protocolrequest::Parent>::entries_end_ =
    &entries_[4];

::fidl::DispatchResult fidl::internal::WireServerDispatcher<::test_protocolrequest::Parent>::TryDispatch(
    ::fidl::WireServer<::test_protocolrequest::Parent>* impl, ::fidl::IncomingMessage& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, storage_view, txn, entries_, entries_end_);
}

void fidl::internal::WireServerDispatcher<::test_protocolrequest::Parent>::Dispatch(::fidl::WireServer<::test_protocolrequest::Parent>* impl, ::fidl::IncomingMessage&& msg,
                                                                                    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_);
}
void fidl::WireServer<::test_protocolrequest::Parent>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::WireServerDispatcher<::test_protocolrequest::Parent>::Dispatch(this, std::move(msg), storage_view, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<::test_protocolrequest::Parent::GetChild>::Reply(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
  return MakeReply(std::move(c));
}

void fidl::internal::WireCompleterImpl<::test_protocolrequest::Parent::GetChild>::MakeReply(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
  ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild> _response{std::move(c)};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>, ::fidl::internal::ChannelTransport>
      _response_message{
          ::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}

void fidl::internal::WireBufferCompleterImpl<::test_protocolrequest::Parent::GetChild>::Reply(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
  return MakeReply(std::move(c));
}

void fidl::internal::WireBufferCompleterImpl<::test_protocolrequest::Parent::GetChild>::MakeReply(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
  ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild> _response{std::move(c)};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<::test_protocolrequest::Parent::GetChild>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure, ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>, ::fidl::internal::ChannelTransport>
      _response_message(
          _allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<::test_protocolrequest::Parent::GetChildRequest>::Reply(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
  return MakeReply(std::move(r));
}

void fidl::internal::WireCompleterImpl<::test_protocolrequest::Parent::GetChildRequest>::MakeReply(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
  ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest> _response{std::move(r)};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>, ::fidl::internal::ChannelTransport>
      _response_message{
          ::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}

void fidl::internal::WireBufferCompleterImpl<::test_protocolrequest::Parent::GetChildRequest>::Reply(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
  return MakeReply(std::move(r));
}

void fidl::internal::WireBufferCompleterImpl<::test_protocolrequest::Parent::GetChildRequest>::MakeReply(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
  ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest> _response{std::move(r)};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<::test_protocolrequest::Parent::GetChildRequest>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure, ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>, ::fidl::internal::ChannelTransport>
      _response_message(
          _allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
#endif  // __Fuchsia__

void ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChild>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_protocolrequest::kParent_GetChild_Ordinal, ::test_protocolrequest::kParent_GetChild_DynamicFlags);
}

#ifdef __Fuchsia__

void ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChild>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_protocolrequest::kParent_GetChild_Ordinal, ::test_protocolrequest::kParent_GetChild_DynamicFlags);
}
#endif  // __Fuchsia__

void ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::GetChildRequest>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_protocolrequest::kParent_GetChildRequest_Ordinal, ::test_protocolrequest::kParent_GetChildRequest_DynamicFlags);
}

#ifdef __Fuchsia__

void ::fidl::internal::TransactionalResponse<::test_protocolrequest::Parent::GetChildRequest>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_protocolrequest::kParent_GetChildRequest_Ordinal, ::test_protocolrequest::kParent_GetChildRequest_DynamicFlags);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

void ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChild>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_protocolrequest::kParent_TakeChild_Ordinal, ::test_protocolrequest::kParent_TakeChild_DynamicFlags);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

void ::fidl::internal::TransactionalRequest<::test_protocolrequest::Parent::TakeChildRequest>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_protocolrequest::kParent_TakeChildRequest_Ordinal, ::test_protocolrequest::kParent_TakeChildRequest_DynamicFlags);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::WireSyncEventHandler<::test_protocolrequest::Child>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_protocolrequest::Child> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_protocolrequest::Child> event_storage;
  fidl::internal::WireEventDispatcher<::test_protocolrequest::Child> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::WireServerDispatcher<::test_protocolrequest::Child>::entries_[] = {};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<::test_protocolrequest::Child>::entries_end_ =
    &entries_[0];

::fidl::DispatchResult fidl::internal::WireServerDispatcher<::test_protocolrequest::Child>::TryDispatch(
    ::fidl::WireServer<::test_protocolrequest::Child>* impl, ::fidl::IncomingMessage& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, storage_view, txn, entries_, entries_end_);
}

void fidl::internal::WireServerDispatcher<::test_protocolrequest::Child>::Dispatch(::fidl::WireServer<::test_protocolrequest::Child>* impl, ::fidl::IncomingMessage&& msg,
                                                                                   internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_);
}
void fidl::WireServer<::test_protocolrequest::Child>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::WireServerDispatcher<::test_protocolrequest::Child>::Dispatch(this, std::move(msg), storage_view, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
