// 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::WireServerDispatcher<
    ::fidl_test_transitivedependenciescompose::Top>::
    TryDispatch(::fidl::WireServer<
                    ::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::WireServer<::fidl_test_transitivedependenciescompose::Top>::
                GetFooCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_transitivedependenciescompose::Top>*>(interface)
                ->GetFoo(reinterpret_cast<::fidl::WireRequest<
                             ::fidl_test_transitivedependenciescompose::Top::
                                 GetFoo>*>(bytes),
                         completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult fidl::internal::WireServerDispatcher<
    ::fidl_test_transitivedependenciescompose::Top>::
    Dispatch(::fidl::WireServer<::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::WireServer<::fidl_test_transitivedependenciescompose::Top>::
    dispatch_message(fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireServerDispatcher<
      ::fidl_test_transitivedependenciescompose::Top>::Dispatch(this, msg, txn);
}

::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::WireServer<::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::WireServer<::fidl_test_transitivedependenciescompose::Top>::
    GetFooCompleterBase::Reply(const ::bottom::wire::Foo& foo) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_transitivedependenciescompose::Top::GetFoo>>
      _response{foo};
  return ::fidl::WireServer<::fidl_test_transitivedependenciescompose::Top>::
      GetFooCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_transitivedependenciescompose::Top>::
    GetFooCompleterBase::Reply(::fidl::BufferSpan _backing_buffer,
                               const ::bottom::wire::Foo& foo) {
  ::fidl::WireResponse<::fidl_test_transitivedependenciescompose::Top::GetFoo>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_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__
