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

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

#include <memory>

namespace fidl_test_bindingsdenylist {
[[maybe_unused]] constexpr uint64_t
    kOnlyLibfuzzerAndDeps_LibfuzzerNeedsNonemptyProtocol_Ordinal =
        2054945783954685224lu;

extern "C" const fidl_type_t
    fidl_test_bindingsdenylist_OnlyLibfuzzerAndDepsLibfuzzerNeedsNonemptyProtocolRequestTable;

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

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

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

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
        LibfuzzerNeedsNonemptyProtocol>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                  LibfuzzerNeedsNonemptyProtocol>::Type,
          ::fidl_test_bindingsdenylist::
              kOnlyLibfuzzerAndDeps_LibfuzzerNeedsNonemptyProtocol_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
        LibfuzzerNeedsNonemptyProtocol>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                  LibfuzzerNeedsNonemptyProtocol>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                     LibfuzzerNeedsNonemptyProtocol>* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(::fidl::WireResponse<
                         ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                             LibfuzzerNeedsNonemptyProtocol>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps>::
    LibfuzzerNeedsNonemptyProtocol(
        ::fidl::WireResponseContext<
            ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                LibfuzzerNeedsNonemptyProtocol>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

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

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

#ifdef __Fuchsia__
::fidl::Result
fidl::WireInterface<::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps>::
    LibfuzzerNeedsNonemptyProtocolCompleterBase::Reply() {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                               LibfuzzerNeedsNonemptyProtocol>>
      _response{};
  return ::fidl::WireInterface<
      ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps>::
      LibfuzzerNeedsNonemptyProtocolCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<
    ::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
        LibfuzzerNeedsNonemptyProtocol>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_bindingsdenylist::
          kOnlyLibfuzzerAndDeps_LibfuzzerNeedsNonemptyProtocol_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_bindingsdenylist::OnlyLibfuzzerAndDeps::
                              LibfuzzerNeedsNonemptyProtocol>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_bindingsdenylist::
          kOnlyLibfuzzerAndDeps_LibfuzzerNeedsNonemptyProtocol_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

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

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::
    WireClientImpl<::fidl_test_bindingsdenylist::OnlyCppAndDeps>::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_bindingsdenylist::OnlyCppAndDeps>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_bindingsdenylist::OnlyCppAndDeps>*
            impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::DispatchResult::kNotFound;
}

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_bindingsdenylist::OnlyCppAndDeps>::Dispatch(
        ::fidl::WireInterface<::fidl_test_bindingsdenylist::OnlyCppAndDeps>*
            impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  txn->InternalError(
      {::fidl::UnbindInfo::kUnexpectedMessage, ZX_ERR_NOT_SUPPORTED});
  return ::fidl::DispatchResult::kNotFound;
}
::fidl::DispatchResult
fidl::WireInterface<::fidl_test_bindingsdenylist::OnlyCppAndDeps>::
    dispatch_message(fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  return ::fidl::internal::WireDispatcher<
      ::fidl_test_bindingsdenylist::OnlyCppAndDeps>::Dispatch(this, msg, txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
