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

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

#include <memory>

namespace llcpp {

namespace fidl {
namespace test {
namespace requestflexibleenvelope {

void ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(StrictFoo) == sizeof(fidl_xunion_t));
  static_assert(offsetof(StrictFoo, ordinal_) == offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(StrictFoo, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}
auto ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo::which() const
    -> Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case Ordinal::kS:
    case Ordinal::kI:
      return static_cast<Tag>(ordinal_);
    default:
      return Tag::kUnknown;
  }
}

void ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(FlexibleFoo) == sizeof(fidl_xunion_t));
  static_assert(offsetof(FlexibleFoo, ordinal_) ==
                offsetof(fidl_xunion_t, tag));
  static_assert(offsetof(FlexibleFoo, envelope_) ==
                offsetof(fidl_xunion_t, envelope));
}

namespace {

[[maybe_unused]] constexpr uint64_t
    kProtocol_RequestStrictResponseFlexible_Ordinal = 4346871690266280218lu;
extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleRequestTable;
extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleResponseTable;
[[maybe_unused]] constexpr uint64_t
    kProtocol_RequestFlexibleResponseStrict_Ordinal = 4374294377437089654lu;
extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictRequestTable;
extern "C" const fidl_type_t
    fidl_test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictResponseTable;

}  // namespace
Protocol::ResultOf::RequestStrictResponseFlexible::
    RequestStrictResponseFlexible(
        zx_handle_t _client,
        ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo& s)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  RequestStrictResponseFlexibleRequest::OwnedEncodedMessage _request(
      zx_txid_t(0), s);
  _request.GetOutgoingMessage().Call<RequestStrictResponseFlexibleResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES);
  status_ = _request.status();
  error_ = _request.error();
}

Protocol::ResultOf::RequestStrictResponseFlexible::
    RequestStrictResponseFlexible(
        zx_handle_t _client,
        ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo& s,
        zx_time_t _deadline)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  RequestStrictResponseFlexibleRequest::OwnedEncodedMessage _request(
      zx_txid_t(0), s);
  _request.GetOutgoingMessage().Call<RequestStrictResponseFlexibleResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES, _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

Protocol::UnownedResultOf::RequestStrictResponseFlexible::
    RequestStrictResponseFlexible(
        zx_handle_t _client, uint8_t* _request_bytes,
        uint32_t _request_byte_capacity,
        ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo& s,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  RequestStrictResponseFlexibleRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, s);
  _request.GetOutgoingMessage().Call<RequestStrictResponseFlexibleResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

Protocol::ResultOf::RequestFlexibleResponseStrict::
    RequestFlexibleResponseStrict(
        zx_handle_t _client,
        ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo& s)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  RequestFlexibleResponseStrictRequest::OwnedEncodedMessage _request(
      zx_txid_t(0), s);
  _request.GetOutgoingMessage().Call<RequestFlexibleResponseStrictResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES);
  status_ = _request.status();
  error_ = _request.error();
}

Protocol::ResultOf::RequestFlexibleResponseStrict::
    RequestFlexibleResponseStrict(
        zx_handle_t _client,
        ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo& s,
        zx_time_t _deadline)
    : bytes_(std::make_unique<
             ::fidl::internal::AlignedBuffer<ZX_CHANNEL_MAX_MSG_BYTES>>()) {
  RequestFlexibleResponseStrictRequest::OwnedEncodedMessage _request(
      zx_txid_t(0), s);
  _request.GetOutgoingMessage().Call<RequestFlexibleResponseStrictResponse>(
      _client, bytes_->data(), ZX_CHANNEL_MAX_MSG_BYTES, _deadline);
  status_ = _request.status();
  error_ = _request.error();
}

Protocol::UnownedResultOf::RequestFlexibleResponseStrict::
    RequestFlexibleResponseStrict(
        zx_handle_t _client, uint8_t* _request_bytes,
        uint32_t _request_byte_capacity,
        ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo& s,
        uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  RequestFlexibleResponseStrictRequest::UnownedEncodedMessage _request(
      _request_bytes, _request_byte_capacity, 0, s);
  _request.GetOutgoingMessage().Call<RequestFlexibleResponseStrictResponse>(
      _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}

Protocol::ResultOf::RequestStrictResponseFlexible
Protocol::ClientImpl::RequestStrictResponseFlexible_Sync(
    ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo s) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::RequestStrictResponseFlexible(_channel->handle(), s);
  }
  return Protocol::ResultOf::RequestStrictResponseFlexible(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

Protocol::UnownedResultOf::RequestStrictResponseFlexible
Protocol::ClientImpl::RequestStrictResponseFlexible_Sync(
    ::fidl::BufferSpan _request_buffer,
    ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo s,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::RequestStrictResponseFlexible(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, s,
        _response_buffer.data, _response_buffer.capacity);
  }
  return Protocol::UnownedResultOf::RequestStrictResponseFlexible(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

Protocol::RequestStrictResponseFlexibleResponseContext::
    RequestStrictResponseFlexibleResponseContext()
    : ::fidl::internal::ResponseContext(
          RequestStrictResponseFlexibleResponse::Type,
          kProtocol_RequestStrictResponseFlexible_Ordinal) {}

void Protocol::RequestStrictResponseFlexibleResponseContext::OnReply(
    uint8_t* reply) {
  OnReply(reinterpret_cast<RequestStrictResponseFlexibleResponse*>(reply));
}

::fidl::Result Protocol::ClientImpl::RequestStrictResponseFlexible(
    ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo s,
    ::fit::callback<void(RequestStrictResponseFlexibleResponse* response)>
        _cb) {
  class ResponseContext final
      : public RequestStrictResponseFlexibleResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(RequestStrictResponseFlexibleResponse* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(RequestStrictResponseFlexibleResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(RequestStrictResponseFlexibleResponse* response)> cb_;
  };

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

::fidl::Result Protocol::ClientImpl::RequestStrictResponseFlexible(
    ::fidl::BufferSpan _request_buffer,
    ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo s,
    RequestStrictResponseFlexibleResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  RequestStrictResponseFlexibleRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), s);
  return _request.GetOutgoingMessage().Write(this, _context);
}

Protocol::ResultOf::RequestFlexibleResponseStrict
Protocol::ClientImpl::RequestFlexibleResponseStrict_Sync(
    ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo s) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ResultOf::RequestFlexibleResponseStrict(_channel->handle(), s);
  }
  return Protocol::ResultOf::RequestFlexibleResponseStrict(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

Protocol::UnownedResultOf::RequestFlexibleResponseStrict
Protocol::ClientImpl::RequestFlexibleResponseStrict_Sync(
    ::fidl::BufferSpan _request_buffer,
    ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo s,
    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return UnownedResultOf::RequestFlexibleResponseStrict(
        _channel->handle(), _request_buffer.data, _request_buffer.capacity, s,
        _response_buffer.data, _response_buffer.capacity);
  }
  return Protocol::UnownedResultOf::RequestFlexibleResponseStrict(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}

Protocol::RequestFlexibleResponseStrictResponseContext::
    RequestFlexibleResponseStrictResponseContext()
    : ::fidl::internal::ResponseContext(
          RequestFlexibleResponseStrictResponse::Type,
          kProtocol_RequestFlexibleResponseStrict_Ordinal) {}

void Protocol::RequestFlexibleResponseStrictResponseContext::OnReply(
    uint8_t* reply) {
  OnReply(reinterpret_cast<RequestFlexibleResponseStrictResponse*>(reply));
}

::fidl::Result Protocol::ClientImpl::RequestFlexibleResponseStrict(
    ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo s,
    ::fit::callback<void(RequestFlexibleResponseStrictResponse* response)>
        _cb) {
  class ResponseContext final
      : public RequestFlexibleResponseStrictResponseContext {
   public:
    ResponseContext(
        ::fit::callback<void(RequestFlexibleResponseStrictResponse* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(RequestFlexibleResponseStrictResponse* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(RequestFlexibleResponseStrictResponse* response)> cb_;
  };

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

::fidl::Result Protocol::ClientImpl::RequestFlexibleResponseStrict(
    ::fidl::BufferSpan _request_buffer,
    ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo s,
    RequestFlexibleResponseStrictResponseContext* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  RequestFlexibleResponseStrictRequest::UnownedEncodedMessage _request(
      _request_buffer.data, _request_buffer.capacity, _context->Txid(), s);
  return _request.GetOutgoingMessage().Write(this, _context);
}

std::optional<::fidl::UnbindInfo> Protocol::ClientImpl::DispatchEvent(
    fidl_incoming_msg_t* msg) {
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(msg->bytes);
  switch (hdr->ordinal) {
    default:
      FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
      return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                                ZX_ERR_NOT_SUPPORTED};
  }
  return {};
}

namespace methods {

void ProtocolDispatchRequestStrictResponseFlexible(void* interface, void* bytes,
                                                   ::fidl::Transaction* txn) {
  auto message =
      reinterpret_cast<Protocol::RequestStrictResponseFlexibleRequest*>(bytes);
  Protocol::Interface::RequestStrictResponseFlexibleCompleter::Sync completer(
      txn);
  reinterpret_cast<Protocol::Interface*>(interface)
      ->RequestStrictResponseFlexible(std::move(message->s), completer);
}

void ProtocolDispatchRequestFlexibleResponseStrict(void* interface, void* bytes,
                                                   ::fidl::Transaction* txn) {
  auto message =
      reinterpret_cast<Protocol::RequestFlexibleResponseStrictRequest*>(bytes);
  Protocol::Interface::RequestFlexibleResponseStrictCompleter::Sync completer(
      txn);
  reinterpret_cast<Protocol::Interface*>(interface)
      ->RequestFlexibleResponseStrict(std::move(message->s), completer);
}

}  // namespace methods

namespace entries {

::fidl::internal::MethodEntry Protocol[] = {
    {kProtocol_RequestStrictResponseFlexible_Ordinal,
     Protocol::RequestStrictResponseFlexibleRequest::Type,
     methods::ProtocolDispatchRequestStrictResponseFlexible},
    {kProtocol_RequestFlexibleResponseStrict_Ordinal,
     Protocol::RequestFlexibleResponseStrictRequest::Type,
     methods::ProtocolDispatchRequestFlexibleResponseStrict},
};

}  // namespace entries

::fidl::DispatchResult Protocol::TryDispatch(Interface* impl,
                                             fidl_incoming_msg_t* msg,
                                             ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries::Protocol,
      entries::Protocol +
          sizeof(entries::Protocol) / sizeof(::fidl::internal::MethodEntry));
}

::fidl::DispatchResult Protocol::Dispatch(Interface* 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 Protocol::Interface::dispatch_message(
    fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return Protocol::Dispatch(this, msg, txn);
}

::fidl::Result
Protocol::Interface::RequestStrictResponseFlexibleCompleterBase::Reply(
    ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo f) {
  RequestStrictResponseFlexibleResponse::OwnedEncodedMessage _response{f};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result
Protocol::Interface::RequestStrictResponseFlexibleCompleterBase::Reply(
    ::fidl::BufferSpan _buffer,
    ::llcpp::fidl::test::requestflexibleenvelope::FlexibleFoo f) {
  RequestStrictResponseFlexibleResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, f);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result
Protocol::Interface::RequestFlexibleResponseStrictCompleterBase::Reply(
    ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo f) {
  RequestFlexibleResponseStrictResponse::OwnedEncodedMessage _response{f};
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

::fidl::Result
Protocol::Interface::RequestFlexibleResponseStrictCompleterBase::Reply(
    ::fidl::BufferSpan _buffer,
    ::llcpp::fidl::test::requestflexibleenvelope::StrictFoo f) {
  RequestFlexibleResponseStrictResponse::UnownedEncodedMessage _response(
      _buffer.data, _buffer.capacity, f);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}

void Protocol::RequestStrictResponseFlexibleRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       kProtocol_RequestStrictResponseFlexible_Ordinal);
}

void Protocol::RequestStrictResponseFlexibleResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       kProtocol_RequestStrictResponseFlexible_Ordinal);
}

void Protocol::RequestFlexibleResponseStrictRequest::_InitHeader(
    zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       kProtocol_RequestFlexibleResponseStrict_Ordinal);
}

void Protocol::RequestFlexibleResponseStrictResponse::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       kProtocol_RequestFlexibleResponseStrict_Ordinal);
}

}  // namespace requestflexibleenvelope
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
