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

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

#include <memory>

namespace fidl_test_inheritancewithrecursivedecl {
[[maybe_unused]] constexpr uint64_t kParent_First_Ordinal =
    3051519745671742363lu;

extern "C" const fidl_type_t
    fidl_test_inheritancewithrecursivedecl_ParentFirstRequestTable;

extern "C" const fidl_type_t
    fidl_test_inheritancewithrecursivedecl_ParentFirstResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_inheritancewithrecursivedecl
::fidl::WireResult<::fidl_test_inheritancewithrecursivedecl::Parent::First>::
    WireResult(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Parent>
            _client,
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  ::fidl::OwnedEncodedMessage<::fidl::WireRequest<
      ::fidl_test_inheritancewithrecursivedecl::Parent::First>>
      _request(zx_txid_t(0), std::move(request));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_inheritancewithrecursivedecl {
#endif  // __Fuchsia__

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

}  // namespace fidl_test_inheritancewithrecursivedecl
#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_inheritancewithrecursivedecl::Parent>::First(
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_inheritancewithrecursivedecl::Parent::First>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Parent>(
            _channel->handle()),
        std::move(request));
    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_inheritancewithrecursivedecl::Parent>::First(
        ::fidl::BufferSpan _request_buffer,
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_inheritancewithrecursivedecl::Parent::First>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Parent>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(request));
    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_inheritancewithrecursivedecl::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_inheritancewithrecursivedecl::Parent>::
    TryDispatch(::fidl::WireInterface<
                    ::fidl_test_inheritancewithrecursivedecl::Parent>* impl,
                fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_inheritancewithrecursivedecl::kParent_First_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_inheritancewithrecursivedecl::Parent::First>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_inheritancewithrecursivedecl::Parent::First>*>(
                bytes);
            ::fidl::WireInterface<
                ::fidl_test_inheritancewithrecursivedecl::Parent>::
                FirstCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_inheritancewithrecursivedecl::Parent>*>(interface)
                ->First(std::move(message->request), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

void ::fidl::WireRequest<::fidl_test_inheritancewithrecursivedecl::Parent::
                             First>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_inheritancewithrecursivedecl::kParent_First_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_inheritancewithrecursivedecl::Parent::First>::_CloseHandles() {
  request.reset();
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

namespace fidl_test_inheritancewithrecursivedecl {
[[maybe_unused]] constexpr uint64_t kChild_First_Ordinal =
    3051519745671742363lu;

extern "C" const fidl_type_t
    fidl_test_inheritancewithrecursivedecl_ChildFirstRequestTable;

extern "C" const fidl_type_t
    fidl_test_inheritancewithrecursivedecl_ChildFirstResponseTable;

[[maybe_unused]] constexpr uint64_t kChild_Second_Ordinal =
    489667253787160198lu;

extern "C" const fidl_type_t
    fidl_test_inheritancewithrecursivedecl_ChildSecondRequestTable;

extern "C" const fidl_type_t
    fidl_test_inheritancewithrecursivedecl_ChildSecondResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_inheritancewithrecursivedecl
::fidl::WireResult<::fidl_test_inheritancewithrecursivedecl::Child::First>::
    WireResult(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Child>
            _client,
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  ::fidl::OwnedEncodedMessage<::fidl::WireRequest<
      ::fidl_test_inheritancewithrecursivedecl::Child::First>>
      _request(zx_txid_t(0), std::move(request));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_inheritancewithrecursivedecl {
#endif  // __Fuchsia__

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

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

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

}  // namespace fidl_test_inheritancewithrecursivedecl
#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_inheritancewithrecursivedecl::Child>::First(
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_inheritancewithrecursivedecl::Child::First>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Child>(
            _channel->handle()),
        std::move(request));
    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_inheritancewithrecursivedecl::Child>::First(
        ::fidl::BufferSpan _request_buffer,
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_inheritancewithrecursivedecl::Child::First>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Child>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(request));
    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_inheritancewithrecursivedecl::Child>::Second(
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_inheritancewithrecursivedecl::Child::Second>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Child>(
            _channel->handle()),
        std::move(request));
    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_inheritancewithrecursivedecl::Child>::Second(
        ::fidl::BufferSpan _request_buffer,
        ::fidl::ServerEnd<::fidl_test_inheritancewithrecursivedecl::Parent>&&
            request) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_inheritancewithrecursivedecl::Child::Second>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_inheritancewithrecursivedecl::Child>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(request));
    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_inheritancewithrecursivedecl::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_inheritancewithrecursivedecl::Child>::
    TryDispatch(::fidl::WireInterface<
                    ::fidl_test_inheritancewithrecursivedecl::Child>* impl,
                fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_inheritancewithrecursivedecl::kChild_First_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_inheritancewithrecursivedecl::Child::First>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_inheritancewithrecursivedecl::Child::First>*>(
                bytes);
            ::fidl::WireInterface<
                ::fidl_test_inheritancewithrecursivedecl::Child>::
                FirstCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_inheritancewithrecursivedecl::Child>*>(interface)
                ->First(std::move(message->request), completer);
          },
      },
      {
          ::fidl_test_inheritancewithrecursivedecl::kChild_Second_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_inheritancewithrecursivedecl::Child::Second>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_inheritancewithrecursivedecl::Child::Second>*>(
                bytes);
            ::fidl::WireInterface<
                ::fidl_test_inheritancewithrecursivedecl::Child>::
                SecondCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_inheritancewithrecursivedecl::Child>*>(interface)
                ->Second(std::move(message->request), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

void ::fidl::WireRequest<::fidl_test_inheritancewithrecursivedecl::Child::
                             First>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_inheritancewithrecursivedecl::kChild_First_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_inheritancewithrecursivedecl::Child::First>::_CloseHandles() {
  request.reset();
}

void ::fidl::WireRequest<::fidl_test_inheritancewithrecursivedecl::Child::
                             Second>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_inheritancewithrecursivedecl::kChild_Second_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_inheritancewithrecursivedecl::Child::Second>::_CloseHandles() {
  request.reset();
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
