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

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

#include <memory>

void ::fidl_test_error::wire::Example_foo_Result::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(Example_foo_Result) == sizeof(fidl_xunion_t));
  static_assert(offsetof(Example_foo_Result, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(Example_foo_Result, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

namespace fidl_test_error {
[[maybe_unused]] constexpr uint64_t kExample_foo_Ordinal =
    6333213382893778862lu;

extern "C" const fidl_type_t fidl_test_error_ExamplefooRequestTable;

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

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

#ifdef __Fuchsia__
}  // namespace fidl_test_error
::fidl::WireUnownedResult<::fidl_test_error::Example::foo>::WireUnownedResult(
    ::fidl::UnownedClientEnd<::fidl_test_error::Example> _client,
    uint8_t* _request_bytes, uint32_t _request_byte_capacity,
    ::fidl::StringView s, uint8_t* _response_bytes,
    uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_error::Example::foo>>
      _request(_request_bytes, _request_byte_capacity, 0, s);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<::fidl_test_error::Example::foo>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_error {
#endif  // __Fuchsia__

}  // namespace fidl_test_error
#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_error::Example::foo>
fidl::internal::WireClientImpl<::fidl_test_error::Example>::foo_Sync(
    ::fidl::StringView s) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_error::Example::foo>(
        ::fidl::UnownedClientEnd<::fidl_test_error::Example>(
            _channel->handle()),
        s);
  }
  return ::fidl::WireResult<::fidl_test_error::Example::foo>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_error::Example::foo>
fidl::internal::WireClientImpl<::fidl_test_error::Example>::foo_Sync(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView s,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<::fidl_test_error::Example::foo>(
        ::fidl::UnownedClientEnd<::fidl_test_error::Example>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, s,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<::fidl_test_error::Example::foo>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_error::Example::foo>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<::fidl_test_error::Example::foo>::Type,
          ::fidl_test_error::kExample_foo_Ordinal) {}

void ::fidl::WireResponseContext<::fidl_test_error::Example::foo>::OnReply(
    uint8_t* reply) {
  OnReply(
      reinterpret_cast<::fidl::WireResponse<::fidl_test_error::Example::foo>*>(
          reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<::fidl_test_error::Example>::foo(
    ::fidl::StringView s,
    ::fit::callback<
        void(::fidl::WireResponse<::fidl_test_error::Example::foo>* response)>
        _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<::fidl_test_error::Example::foo> {
   public:
    ResponseContext(
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_error::Example::foo>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(::fidl::WireResponse<::fidl_test_error::Example::foo>*
                     response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_error::Example::foo>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::WireClientImpl<::fidl_test_error::Example>::foo(
    ::fidl::BufferSpan _request_buffer, ::fidl::StringView s,
    ::fidl::WireResponseContext<::fidl_test_error::Example::foo>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_error::Example::foo>::UnownedEncodedMessage
      _request(_request_buffer.data, _request_buffer.capacity, _context->Txid(),
               s);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_error::Example>::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_error::Example>::TryDispatch(
    ::fidl::WireInterface<::fidl_test_error::Example>* impl,
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_error::kExample_foo_Ordinal,
          ::fidl::WireRequest<::fidl_test_error::Example::foo>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<
                ::fidl::WireRequest<::fidl_test_error::Example::foo>*>(bytes);
            ::fidl::WireInterface<
                ::fidl_test_error::Example>::fooCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_error::Example>*>(interface)
                ->foo(std::move(message->s), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

#ifdef __Fuchsia__
::fidl::Result
fidl::WireInterface<::fidl_test_error::Example>::fooCompleterBase::Reply(
    ::fidl_test_error::wire::Example_foo_Result result) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_error::Example::foo>>
      _response{result};
  return ::fidl::WireInterface<::fidl_test_error::Example>::fooCompleterBase::
      SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<
    ::fidl_test_error::Example>::fooCompleterBase::ReplySuccess(int64_t y) {
  ::fidl_test_error::wire::Example_foo_Response _response;
  _response.y = std::move(y);

  return Reply(::fidl_test_error::wire::Example_foo_Result::WithResponse(
      ::fidl::ObjectView<::fidl_test_error::wire::Example_foo_Response>::
          FromExternal(&_response)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireInterface<
    ::fidl_test_error::Example>::fooCompleterBase::ReplyError(uint32_t error) {
  return Reply(::fidl_test_error::wire::Example_foo_Result::WithErr(
      ::fidl::ObjectView<uint32_t>::FromExternal(&error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireInterface<::fidl_test_error::Example>::fooCompleterBase::Reply(
    ::fidl::BufferSpan _buffer,
    ::fidl_test_error::wire::Example_foo_Result result) {
  ::fidl::WireResponse<::fidl_test_error::Example::foo>::UnownedEncodedMessage
      _response(_buffer.data, _buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireInterface<::fidl_test_error::Example>::fooCompleterBase::ReplySuccess(
    ::fidl::BufferSpan _buffer, int64_t y) {
  ::fidl_test_error::wire::Example_foo_Response response;
  response.y = std::move(y);

  return Reply(
      std::move(_buffer),
      ::fidl_test_error::wire::Example_foo_Result::WithResponse(
          ::fidl::ObjectView<::fidl_test_error::wire::Example_foo_Response>::
              FromExternal(&response)));
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<::fidl_test_error::Example::foo>::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid, ::fidl_test_error::kExample_foo_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_error::Example::foo>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0, ::fidl_test_error::kExample_foo_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
