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

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

#include <memory>

namespace fidl_test_transitivedependenciescompose {
[[maybe_unused]] constexpr uint64_t kTop_GetFoo_Ordinal = 3210163844600846111lu;

extern "C" const fidl_type_t
    fidl_test_transitivedependenciescompose_TopGetFooRequestTable;

extern "C" const fidl_type_t
    fidl_test_transitivedependenciescompose_TopGetFooResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_transitivedependenciescompose
::fidl::WireResult<::fidl_test_transitivedependenciescompose::Top::GetFoo>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_transitivedependenciescompose::Top>
            _client) {
  ::fidl::OwnedEncodedMessage<::fidl::WireRequest<
      ::fidl_test_transitivedependenciescompose::Top::GetFoo>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_transitivedependenciescompose::Top::GetFoo>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

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

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

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

#ifdef __Fuchsia__

::fidl::WireResponseContext<::fidl_test_transitivedependenciescompose::Top::
                                GetFoo>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_transitivedependenciescompose::Top::GetFoo>::Type,
          ::fidl_test_transitivedependenciescompose::kTop_GetFoo_Ordinal) {}

void ::fidl::WireResponseContext<::fidl_test_transitivedependenciescompose::
                                     Top::GetFoo>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_transitivedependenciescompose::Top::GetFoo>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_transitivedependenciescompose::Top::GetFoo>*
                     response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<
            ::fidl_test_transitivedependenciescompose::Top::GetFoo>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_transitivedependenciescompose::Top>::GetFoo(
        ::fidl::WireResponseContext<
            ::fidl_test_transitivedependenciescompose::Top::GetFoo>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo>
fidl::internal::WireClientImpl<::fidl_test_transitivedependenciescompose::Top>::
    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_transitivedependenciescompose::Top>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_transitivedependenciescompose::Top>*
            impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_transitivedependenciescompose::kTop_GetFoo_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_transitivedependenciescompose::Top::GetFoo>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireInterface<
                ::fidl_test_transitivedependenciescompose::Top>::
                GetFooCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_transitivedependenciescompose::Top>*>(interface)
                ->GetFoo(completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

#ifdef __Fuchsia__
::fidl::Result
fidl::WireInterface<::fidl_test_transitivedependenciescompose::Top>::
    GetFooCompleterBase::Reply(const ::bottom::wire::Foo& foo) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_transitivedependenciescompose::Top::GetFoo>>
      _response{foo};
  return ::fidl::WireInterface<::fidl_test_transitivedependenciescompose::Top>::
      GetFooCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireInterface<::fidl_test_transitivedependenciescompose::Top>::
    GetFooCompleterBase::Reply(::fidl::BufferSpan _buffer,
                               const ::bottom::wire::Foo& foo) {
  ::fidl::WireResponse<::fidl_test_transitivedependenciescompose::Top::GetFoo>::
      UnownedEncodedMessage _response(_buffer.data, _buffer.capacity, foo);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<::fidl_test_transitivedependenciescompose::Top::
                             GetFoo>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_transitivedependenciescompose::kTop_GetFoo_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_transitivedependenciescompose::Top::GetFoo>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, ::fidl_test_transitivedependenciescompose::kTop_GetFoo_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
