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

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

#include <memory>

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

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

namespace fidl_test_protocols {
[[maybe_unused]] constexpr uint64_t kDiscoverableProtocol_Method_Ordinal =
    16177161678225767lu;

extern "C" const fidl_type_t
    fidl_test_protocols_DiscoverableProtocolMethodRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_DiscoverableProtocolMethodResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::DiscoverableProtocol::Method>::
    WireResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::DiscoverableProtocol>
            _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::DiscoverableProtocol::Method>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

}  // namespace fidl_test_protocols
#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::DiscoverableProtocol>::Method() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_protocols::DiscoverableProtocol::Method>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::DiscoverableProtocol>(
            _channel->handle()));
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::
    WireClientImpl<::fidl_test_protocols::DiscoverableProtocol>::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_protocols::DiscoverableProtocol>::
    TryDispatch(
        ::fidl::WireServer<::fidl_test_protocols::DiscoverableProtocol>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kDiscoverableProtocol_Method_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::DiscoverableProtocol::Method>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::DiscoverableProtocol>::
                MethodCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::DiscoverableProtocol>*>(interface)
                ->Method(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::DiscoverableProtocol::Method>*>(
                        bytes),
                    completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_protocols::DiscoverableProtocol>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_protocols::DiscoverableProtocol>*
            impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kDiscoverableProtocol_Method_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::DiscoverableProtocol::Method>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::DiscoverableProtocol>::
                MethodCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::DiscoverableProtocol>*>(interface)
                ->Method(completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

void ::fidl::WireRequest<::fidl_test_protocols::DiscoverableProtocol::Method>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::kDiscoverableProtocol_Method_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

namespace fidl_test_protocols {
[[maybe_unused]] constexpr uint64_t kTransitional_Request_Ordinal =
    7121112290509197032lu;

extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestResponseTable;

[[maybe_unused]] constexpr uint64_t kTransitional_OneWay_Ordinal =
    1124136612964114085lu;

extern "C" const fidl_type_t fidl_test_protocols_TransitionalOneWayRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalOneWayResponseTable;

[[maybe_unused]] constexpr uint64_t kTransitional_Event_Ordinal =
    6033576734966581606lu;

extern "C" const fidl_type_t fidl_test_protocols_TransitionalEventRequestTable;

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

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

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay>::WireResult(
    ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
    int64_t x) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay>>
      _request(zx_txid_t(0), x);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::OneWay>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t x) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay>>
      _request(_request_bytes, _request_byte_capacity, 0, x);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

}  // namespace fidl_test_protocols
#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::Transitional::Request>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::Transitional>::Request_Sync(int64_t x) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::Request>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional>(
            _channel->handle()),
        x);
  }
  return ::fidl::WireResult<::fidl_test_protocols::Transitional::Request>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::Request> fidl::
    internal::WireClientImpl<::fidl_test_protocols::Transitional>::Request_Sync(
        ::fidl::BufferSpan _request_buffer, int64_t x,
        ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::Request>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, x,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocols::Transitional::Request>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::Transitional::Request>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::Transitional::Request>::Type,
          ::fidl_test_protocols::kTransitional_Request_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::Transitional::Request>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*>(
      reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocols::Transitional>::Request(
    int64_t x,
    ::fit::callback<
        void(::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
                 response)>
        _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_protocols::Transitional::Request> {
   public:
    ResponseContext(
        ::fit::callback<void(
            ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
                response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
            response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
            response)>
        cb_;
  };

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

::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocols::Transitional>::Request(
    ::fidl::BufferSpan _request_buffer, int64_t x,
    ::fidl::WireResponseContext<::fidl_test_protocols::Transitional::Request>*
        _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocols::Transitional::Request>::
      UnownedEncodedMessage _request(
          _request_buffer.data, _request_buffer.capacity, _context->Txid(), x);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::Transitional>::OneWay(int64_t x) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional>(
            _channel->handle()),
        x);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocols::Transitional>::OneWay(
    ::fidl::BufferSpan _request_buffer, int64_t x) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res =
        ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::OneWay>(
            ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional>(
                _channel->handle()),
            _request_buffer.data, _request_buffer.capacity, x);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_protocols::Transitional>::DispatchEvent(fidl_incoming_msg_t*
                                                            msg) {
  if (event_handler_ != nullptr) {
    fidl_message_header_t* hdr =
        reinterpret_cast<fidl_message_header_t*>(msg->bytes);
    switch (hdr->ordinal) {
      case ::fidl_test_protocols::kTransitional_Event_Ordinal: {
        const char* error_message;
        zx_status_t status = fidl_decode_etc(
            ::fidl::WireResponse<
                ::fidl_test_protocols::Transitional::Event>::Type,
            msg->bytes, msg->num_bytes, msg->handles, msg->num_handles,
            &error_message);
        if (status != ZX_OK) {
          return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
        }
        event_handler_->Event(
            reinterpret_cast<::fidl::WireResponse<
                ::fidl_test_protocols::Transitional::Event>*>(msg->bytes));
        return std::nullopt;
      }
      default:
        break;
    }
  }
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                            ZX_ERR_NOT_SUPPORTED};
}
#endif  // __Fuchsia__

::fidl::Result
fidl::WireSyncEventHandler<::fidl_test_protocols::Transitional>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> client_end) {
  zx_status_t status = client_end.channel()->wait_one(
      ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, ::zx::time::infinite(),
      nullptr);
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorWaitOneFailed);
  }
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::WireResponse<
            ::fidl_test_protocols::Transitional::Event>::MaxNumHandles >= x) {
      x = ::fidl::WireResponse<
          ::fidl_test_protocols::Transitional::Event>::MaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  ::fidl::internal::InlineMessageBuffer<24> read_storage;
  uint8_t* read_bytes = read_storage.data();
  zx_handle_info_t read_handles[kHandleAllocSize];
  uint32_t actual_bytes;
  uint32_t actual_handles;
  status = client_end.channel()->read_etc(
      ZX_CHANNEL_READ_MAY_DISCARD, read_bytes, read_handles,
      read_storage.size(), kHandleAllocSize, &actual_bytes, &actual_handles);
  if (status == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Result(Unknown(), nullptr);
  }
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorReadFailed);
  }
  if (actual_bytes < sizeof(fidl_message_header_t)) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(ZX_ERR_INVALID_ARGS, ::fidl::kErrorInvalidHeader);
  }
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(read_bytes);
  status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(status, ::fidl::kErrorInvalidHeader);
  }
  switch (hdr->ordinal) {
    case ::fidl_test_protocols::kTransitional_Event_Ordinal: {
      const char* error_message;
      zx_status_t status =
          fidl_decode_etc(::fidl::WireResponse<
                              ::fidl_test_protocols::Transitional::Event>::Type,
                          read_bytes, actual_bytes, read_handles,
                          actual_handles, &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      Event(reinterpret_cast<
            ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>*>(
          read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    default: {
      FidlHandleInfoCloseMany(read_handles, actual_handles);
      return ::fidl::Result(Unknown(), nullptr);
    }
  }
}

#ifdef __Fuchsia__

::fidl::DispatchResult fidl::internal::
    WireServerDispatcher<::fidl_test_protocols::Transitional>::TryDispatch(
        ::fidl::WireServer<::fidl_test_protocols::Transitional>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kTransitional_Request_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::Transitional::Request>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::Transitional>::
                RequestCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::Transitional>*>(
                interface)
                ->Request(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::Transitional::Request>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::kTransitional_OneWay_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::Transitional::OneWay>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::Transitional>::
                OneWayCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::Transitional>*>(
                interface)
                ->OneWay(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::Transitional::OneWay>*>(bytes),
                    completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_protocols::Transitional>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_protocols::Transitional>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kTransitional_Request_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::Transitional::Request>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::Transitional::Request>*>(bytes);
            ::fidl::WireServer<::fidl_test_protocols::Transitional>::
                RequestCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::Transitional>*>(
                interface)
                ->Request(std::move(message->x), completer);
          },
      },
      {
          ::fidl_test_protocols::kTransitional_OneWay_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::Transitional::OneWay>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::Transitional::OneWay>*>(bytes);
            ::fidl::WireServer<::fidl_test_protocols::Transitional>::
                OneWayCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::Transitional>*>(
                interface)
                ->OneWay(std::move(message->x), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::Transitional>::
    RequestCompleterBase::Reply(int64_t y) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>
      _response{y};
  return ::fidl::WireServer<::fidl_test_protocols::Transitional>::
      RequestCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::Transitional>::
    RequestCompleterBase::Reply(::fidl::BufferSpan _backing_buffer, int64_t y) {
  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_buffer.capacity, y);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<::fidl_test_protocols::Transitional::Request>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_protocols::kTransitional_Request_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::Transitional::Request>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_protocols::kTransitional_Request_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_protocols::Transitional::OneWay>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_protocols::kTransitional_OneWay_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::Transitional::Event>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_protocols::kTransitional_Event_Ordinal);
}

#ifdef __Fuchsia__

zx_status_t fidl::WireEventSender<::fidl_test_protocols::Transitional>::Event(
    int64_t x) const {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>
      _response{x};
  _response.Write(server_end_);
  return _response.status();
}

zx_status_t fidl::WireEventSender<::fidl_test_protocols::Transitional>::Event(
    ::fidl::BufferSpan _buffer, int64_t x) const {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>
      _response(_buffer.data, _buffer.capacity, x);
  _response.Write(server_end_);
  return _response.status();
}

#endif  // __Fuchsia__

namespace fidl_test_protocols {
[[maybe_unused]] constexpr uint64_t kChannelProtocol_MethodA_Ordinal =
    565531679656837166lu;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodARequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodAResponseTable;

[[maybe_unused]] constexpr uint64_t kChannelProtocol_EventA_Ordinal =
    5963604044179602938lu;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventARequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventAEventTable;

[[maybe_unused]] constexpr uint64_t kChannelProtocol_MethodB_Ordinal =
    6746905632127147242lu;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBResponseTable;

[[maybe_unused]] constexpr uint64_t kChannelProtocol_TakeHandle_Ordinal =
    875219241480379432lu;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleResponseTable;

[[maybe_unused]] constexpr uint64_t kChannelProtocol_MutateSocket_Ordinal =
    9065806117349865322lu;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketResponseTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA>::WireResult(
    ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
    int64_t a, int64_t b) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>>
      _request(zx_txid_t(0), a, b);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodA>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
            _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t a,
        int64_t b) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>>
      _request(_request_bytes, _request_byte_capacity, 0, a, b);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>::WireResult(
    ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
    int64_t a, int64_t b) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>>
      _request(zx_txid_t(0), a, b);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodB>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
            _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t a,
        int64_t b, uint8_t* _response_bytes, uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>>
      _request(_request_bytes, _request_byte_capacity, 0, a, b);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>::
    WireResult(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                   _client,
               ::zx::handle&& h) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
      _request(zx_txid_t(0), std::move(h));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>::
    WireResult(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                   _client,
               ::zx::handle&& h, zx_time_t _deadline) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
      _request(zx_txid_t(0), std::move(h));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>(
          _client, bytes_.data(), bytes_.size(), _deadline);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
            _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity,
        ::zx::handle&& h, uint8_t* _response_bytes,
        uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
      _request(_request_bytes, _request_byte_capacity, 0, std::move(h));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>::
    WireResult(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                   _client,
               ::zx::socket&& a) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
      _request(zx_txid_t(0), std::move(a));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>::
    WireResult(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                   _client,
               ::zx::socket&& a, zx_time_t _deadline) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
      _request(zx_txid_t(0), std::move(a));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>(
          _client, bytes_.data(), bytes_.size(), _deadline);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireUnownedResult<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>::
    WireUnownedResult(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
            _client,
        uint8_t* _request_bytes, uint32_t _request_byte_capacity,
        ::zx::socket&& a, uint8_t* _response_bytes,
        uint32_t _response_byte_capacity)
    : bytes_(_response_bytes) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
      _request(_request_bytes, _request_byte_capacity, 0, std::move(a));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>(
          _client, _response_bytes, _response_byte_capacity);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

}  // namespace fidl_test_protocols
#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::ChannelProtocol>::MethodA(int64_t a, int64_t b) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res =
        ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA>(
            ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
                _channel->handle()),
            a, b);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::MethodA(
    ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodA>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, a, b);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::ChannelProtocol>::MethodB_Sync(int64_t a,
                                                          int64_t b) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        a, b);
  }
  return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodB>
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::
    MethodB_Sync(::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
                 ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodB>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, a, b,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MethodB>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::MethodB>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::MethodB>::Type,
          ::fidl_test_protocols::kChannelProtocol_MethodB_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::MethodB>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::MethodB>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::MethodB(
    int64_t a, int64_t b,
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
            response)>
        _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_protocols::ChannelProtocol::MethodB> {
   public:
    ResponseContext(
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::MethodB>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
            response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
            response)>
        cb_;
  };

  auto* _context = new ResponseContext(std::move(_cb));
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);
  ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>::
      OwnedEncodedMessage _request(_context->Txid(), a, b);
  return _request.GetOutgoingMessage().Write(this, _context);
}

::fidl::Result
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::MethodB(
    ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
    ::fidl::WireResponseContext<
        ::fidl_test_protocols::ChannelProtocol::MethodB>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>::
      UnownedEncodedMessage _request(_request_buffer.data,
                                     _request_buffer.capacity, _context->Txid(),
                                     a, b);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::ChannelProtocol>::TakeHandle_Sync(::zx::handle&& h) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        std::move(h));
  }
  return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::
    TakeHandle_Sync(::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
                    ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(h),
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::TakeHandle>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::TakeHandle>::Type,
          ::fidl_test_protocols::kChannelProtocol_TakeHandle_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::TakeHandle>::OnReply(uint8_t*
                                                                     reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::ChannelProtocol>::TakeHandle(
        ::zx::handle&& h,
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::TakeHandle>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_protocols::ChannelProtocol::TakeHandle> {
   public:
    ResponseContext(
        ::fit::callback<
            void(::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::TakeHandle>* response)>
            cb)
        : cb_(std::move(cb)) {}

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::TakeHandle>* response)
        override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<
            ::fidl_test_protocols::ChannelProtocol::TakeHandle>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::ChannelProtocol>::TakeHandle(
        ::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::ChannelProtocol::TakeHandle>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>::
      UnownedEncodedMessage _request(_request_buffer.data,
                                     _request_buffer.capacity, _context->Txid(),
                                     std::move(h));
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::
    MutateSocket_Sync(::zx::socket&& a) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        std::move(a));
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>
fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>::
    MutateSocket_Sync(::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
                      ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, std::move(a),
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::MutateSocket>::Type,
          ::fidl_test_protocols::kChannelProtocol_MutateSocket_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>::OnReply(uint8_t*
                                                                       reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(reply));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::ChannelProtocol>::MutateSocket(
        ::zx::socket&& a,
        ::fit::callback<
            void(::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::
                                          MutateSocket>* response)>
            _cb) {
  class ResponseContext final
      : public ::fidl::WireResponseContext<
            ::fidl_test_protocols::ChannelProtocol::MutateSocket> {
   public:
    ResponseContext(::fit::callback<
                    void(::fidl::WireResponse<
                         ::fidl_test_protocols::ChannelProtocol::MutateSocket>*
                             response)>
                        cb)
        : cb_(std::move(cb)) {}

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::MutateSocket>*
                     response) override {
      cb_(response);

      response->_CloseHandles();

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<
            ::fidl_test_protocols::ChannelProtocol::MutateSocket>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::ChannelProtocol>::MutateSocket(
        ::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::ChannelProtocol::MutateSocket>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>::
      UnownedEncodedMessage _request(_request_buffer.data,
                                     _request_buffer.capacity, _context->Txid(),
                                     std::move(a));
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_protocols::ChannelProtocol>::DispatchEvent(fidl_incoming_msg_t*
                                                               msg) {
  if (event_handler_ != nullptr) {
    fidl_message_header_t* hdr =
        reinterpret_cast<fidl_message_header_t*>(msg->bytes);
    switch (hdr->ordinal) {
      case ::fidl_test_protocols::kChannelProtocol_EventA_Ordinal: {
        const char* error_message;
        zx_status_t status = fidl_decode_etc(
            ::fidl::WireResponse<
                ::fidl_test_protocols::ChannelProtocol::EventA>::Type,
            msg->bytes, msg->num_bytes, msg->handles, msg->num_handles,
            &error_message);
        if (status != ZX_OK) {
          return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
        }
        event_handler_->EventA(
            reinterpret_cast<::fidl::WireResponse<
                ::fidl_test_protocols::ChannelProtocol::EventA>*>(msg->bytes));
        return std::nullopt;
      }
      default:
        break;
    }
  }
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                            ZX_ERR_NOT_SUPPORTED};
}
#endif  // __Fuchsia__

::fidl::Result
fidl::WireSyncEventHandler<::fidl_test_protocols::ChannelProtocol>::
    HandleOneEvent(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
            client_end) {
  zx_status_t status = client_end.channel()->wait_one(
      ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, ::zx::time::infinite(),
      nullptr);
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorWaitOneFailed);
  }
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::WireResponse<
            ::fidl_test_protocols::ChannelProtocol::EventA>::MaxNumHandles >=
        x) {
      x = ::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::EventA>::MaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  ::fidl::internal::InlineMessageBuffer<32> read_storage;
  uint8_t* read_bytes = read_storage.data();
  zx_handle_info_t read_handles[kHandleAllocSize];
  uint32_t actual_bytes;
  uint32_t actual_handles;
  status = client_end.channel()->read_etc(
      ZX_CHANNEL_READ_MAY_DISCARD, read_bytes, read_handles,
      read_storage.size(), kHandleAllocSize, &actual_bytes, &actual_handles);
  if (status == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Result(Unknown(), nullptr);
  }
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorReadFailed);
  }
  if (actual_bytes < sizeof(fidl_message_header_t)) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(ZX_ERR_INVALID_ARGS, ::fidl::kErrorInvalidHeader);
  }
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(read_bytes);
  status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(status, ::fidl::kErrorInvalidHeader);
  }
  switch (hdr->ordinal) {
    case ::fidl_test_protocols::kChannelProtocol_EventA_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          ::fidl::WireResponse<
              ::fidl_test_protocols::ChannelProtocol::EventA>::Type,
          read_bytes, actual_bytes, read_handles, actual_handles,
          &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      EventA(reinterpret_cast<::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::EventA>*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    default: {
      FidlHandleInfoCloseMany(read_handles, actual_handles);
      return ::fidl::Result(Unknown(), nullptr);
    }
  }
}

#ifdef __Fuchsia__

::fidl::DispatchResult fidl::internal::
    WireServerDispatcher<::fidl_test_protocols::ChannelProtocol>::TryDispatch(
        ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kChannelProtocol_MethodA_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::MethodA>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                MethodACompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->MethodA(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::ChannelProtocol::MethodA>*>(
                        bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::kChannelProtocol_MethodB_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::MethodB>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                MethodBCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->MethodB(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::ChannelProtocol::MethodB>*>(
                        bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::kChannelProtocol_TakeHandle_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::TakeHandle>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                TakeHandleCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->TakeHandle(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(
                        bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::kChannelProtocol_MutateSocket_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::MutateSocket>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                MutateSocketCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->MutateSocket(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(
                        bytes),
                    completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_protocols::ChannelProtocol>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kChannelProtocol_MethodA_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::MethodA>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::ChannelProtocol::MethodA>*>(bytes);
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                MethodACompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->MethodA(std::move(message->a), std::move(message->b),
                          completer);
          },
      },
      {
          ::fidl_test_protocols::kChannelProtocol_MethodB_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::MethodB>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::ChannelProtocol::MethodB>*>(bytes);
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                MethodBCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->MethodB(std::move(message->a), std::move(message->b),
                          completer);
          },
      },
      {
          ::fidl_test_protocols::kChannelProtocol_TakeHandle_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::TakeHandle>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(bytes);
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                TakeHandleCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->TakeHandle(std::move(message->h), completer);
          },
      },
      {
          ::fidl_test_protocols::kChannelProtocol_MutateSocket_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::ChannelProtocol::MutateSocket>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(bytes);
            ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
                MutateSocketCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>*>(
                interface)
                ->MutateSocket(std::move(message->a), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
    MethodBCompleterBase::Reply(int64_t result) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>>
      _response{result};
  return ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
      MethodBCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
    MethodBCompleterBase::Reply(::fidl::BufferSpan _backing_buffer,
                                int64_t result) {
  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<
    ::fidl_test_protocols::ChannelProtocol>::TakeHandleCompleterBase::Reply() {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
      _response{};
  return ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
      TakeHandleCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
    MutateSocketCompleterBase::Reply(::zx::socket&& b) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>>
      _response{std::move(b)};
  return ::fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
      MutateSocketCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::ChannelProtocol>::
    MutateSocketCompleterBase::Reply(::fidl::BufferSpan _backing_buffer,
                                     ::zx::socket&& b) {
  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_buffer.capacity, std::move(b));
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_protocols::kChannelProtocol_MethodA_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::ChannelProtocol::EventA>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_protocols::kChannelProtocol_EventA_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(&_hdr, _txid,
                       ::fidl_test_protocols::kChannelProtocol_MethodB_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::ChannelProtocol::MethodB>::_InitHeader() {
  fidl_init_txn_header(&_hdr, 0,
                       ::fidl_test_protocols::kChannelProtocol_MethodB_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid, ::fidl_test_protocols::kChannelProtocol_TakeHandle_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_protocols::ChannelProtocol::TakeHandle>::_CloseHandles() {
  h.reset();
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::ChannelProtocol::TakeHandle>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, ::fidl_test_protocols::kChannelProtocol_TakeHandle_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::kChannelProtocol_MutateSocket_Ordinal);
}

void ::fidl::WireRequest<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>::_CloseHandles() {
  a.reset();
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, ::fidl_test_protocols::kChannelProtocol_MutateSocket_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>::_CloseHandles() {
  b.reset();
}

#ifdef __Fuchsia__

zx_status_t
fidl::WireEventSender<::fidl_test_protocols::ChannelProtocol>::EventA(
    int64_t a, int64_t b) const {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>>
      _response{a, b};
  _response.Write(server_end_);
  return _response.status();
}

zx_status_t
fidl::WireEventSender<::fidl_test_protocols::ChannelProtocol>::EventA(
    ::fidl::BufferSpan _buffer, int64_t a, int64_t b) const {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>>
      _response(_buffer.data, _buffer.capacity, a, b);
  _response.Write(server_end_);
  return _response.status();
}

#endif  // __Fuchsia__

namespace fidl_test_protocols {
[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal =
        7699066378708085668lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseResponseTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal =
        4641225961522096302lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseResponseTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal =
        4935493674668456948lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal =
        8985942600963248509lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseResponseTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal =
        7344052883704365182lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseResponseTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal =
        2103802322332450033lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal =
        1323081535741489193lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseEventTable;

[[maybe_unused]] constexpr uint64_t
    kWithAndWithoutRequestResponse_OnWithResponse_Ordinal =
        1691906546593908418lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseEventTable;
#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>::
    WireResult(::fidl::UnownedClientEnd<
               ::fidl_test_protocols::WithAndWithoutRequestResponse>
                   _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              NoRequestNoResponse>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       NoRequestEmptyResponse>::
    WireResult(::fidl::UnownedClientEnd<
               ::fidl_test_protocols::WithAndWithoutRequestResponse>
                   _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              NoRequestEmptyResponse>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>>(_client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       NoRequestWithResponse>::
    WireResult(::fidl::UnownedClientEnd<
               ::fidl_test_protocols::WithAndWithoutRequestResponse>
                   _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              NoRequestWithResponse>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>>(_client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       WithRequestNoResponse>::
    WireResult(::fidl::UnownedClientEnd<
                   ::fidl_test_protocols::WithAndWithoutRequestResponse>
                   _client,
               ::fidl::StringView arg) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestNoResponse>>
      _request(zx_txid_t(0), arg);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireUnownedResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestNoResponse>::
    WireUnownedResult(::fidl::UnownedClientEnd<
                          ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client,
                      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
                      ::fidl::StringView arg) {
  ::fidl::UnownedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestNoResponse>>
      _request(_request_bytes, _request_byte_capacity, 0, arg);
  _request.GetOutgoingMessage().Write(_client);
  status_ = _request.status();
  error_ = _request.error();
}
namespace fidl_test_protocols {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       WithRequestEmptyResponse>::
    WireResult(::fidl::UnownedClientEnd<
                   ::fidl_test_protocols::WithAndWithoutRequestResponse>
                   _client,
               ::fidl::StringView arg) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestEmptyResponse>>
      _request(zx_txid_t(0), arg);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>>(_client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       WithRequestWithResponse>::
    WireResult(::fidl::UnownedClientEnd<
                   ::fidl_test_protocols::WithAndWithoutRequestResponse>
                   _client,
               ::fidl::StringView arg) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestWithResponse>>
      _request(zx_txid_t(0), arg);
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>>(_client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

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

}  // namespace fidl_test_protocols
#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestNoResponse() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestNoResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()));
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       NoRequestEmptyResponse>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestEmptyResponse_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()));
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestEmptyResponse>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestEmptyResponse>::Type,
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestEmptyResponse>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestEmptyResponse>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     NoRequestEmptyResponse>* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(::fidl::WireResponse<
                         ::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestEmptyResponse>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestEmptyResponse(
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                NoRequestEmptyResponse>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

#ifdef __Fuchsia__
::fidl::WireResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestWithResponse>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestWithResponse_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()));
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

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

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestWithResponse>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestWithResponse>::Type,
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestWithResponse>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestWithResponse>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     NoRequestWithResponse>* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(::fidl::WireResponse<
                         ::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestWithResponse>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestWithResponse(::fidl::WireResponseContext<
                          ::fidl_test_protocols::WithAndWithoutRequestResponse::
                              NoRequestWithResponse>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestNoResponse(::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()),
        arg);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestNoResponse(::fidl::BufferSpan _request_buffer,
                          ::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    auto _res = ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, arg);
    return ::fidl::Result(_res.status(), _res.error());
  }
  return ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       WithRequestEmptyResponse>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestEmptyResponse_Sync(::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()),
        arg);
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestEmptyResponse>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestEmptyResponse_Sync(::fidl::BufferSpan _request_buffer,
                                  ::fidl::StringView arg,
                                  ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestEmptyResponse>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestEmptyResponse>::Type,
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal) {
}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestEmptyResponse>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestEmptyResponse>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     WithRequestEmptyResponse>* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(::fidl::WireResponse<
                         ::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestEmptyResponse>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestEmptyResponse(
        ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                WithRequestEmptyResponse>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                          WithRequestEmptyResponse>::UnownedEncodedMessage
      _request(_request_buffer.data, _request_buffer.capacity, _context->Txid(),
               arg);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                       WithRequestWithResponse>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestWithResponse_Sync(::fidl::StringView arg) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()),
        arg);
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::WireUnownedResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestWithResponse>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestWithResponse_Sync(::fidl::BufferSpan _request_buffer,
                                 ::fidl::StringView arg,
                                 ::fidl::BufferSpan _response_buffer) {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(
        ::fidl::UnownedClientEnd<
            ::fidl_test_protocols::WithAndWithoutRequestResponse>(
            _channel->handle()),
        _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }
  return ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestWithResponse>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestWithResponse>::Type,
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestWithResponse>::OnReply(uint8_t* reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestWithResponse>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     WithRequestWithResponse>* response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(::fidl::WireResponse<
                         ::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestWithResponse>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestWithResponse(
        ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                WithRequestWithResponse>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

  ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                          WithRequestWithResponse>::UnownedEncodedMessage
      _request(_request_buffer.data, _request_buffer.capacity, _context->Txid(),
               arg);
  return _request.GetOutgoingMessage().Write(this, _context);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    DispatchEvent(fidl_incoming_msg_t* msg) {
  if (event_handler_ != nullptr) {
    fidl_message_header_t* hdr =
        reinterpret_cast<fidl_message_header_t*>(msg->bytes);
    switch (hdr->ordinal) {
      case ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal: {
        const char* error_message;
        zx_status_t status = fidl_decode_etc(
            ::fidl::WireResponse<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    OnEmptyResponse>::Type,
            msg->bytes, msg->num_bytes, msg->handles, msg->num_handles,
            &error_message);
        if (status != ZX_OK) {
          return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
        }
        event_handler_->OnEmptyResponse(
            reinterpret_cast<::fidl::WireResponse<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    OnEmptyResponse>*>(msg->bytes));
        return std::nullopt;
      }
      case ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_OnWithResponse_Ordinal: {
        const char* error_message;
        zx_status_t status = fidl_decode_etc(
            ::fidl::WireResponse<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    OnWithResponse>::Type,
            msg->bytes, msg->num_bytes, msg->handles, msg->num_handles,
            &error_message);
        if (status != ZX_OK) {
          return ::fidl::UnbindInfo{::fidl::UnbindInfo::kDecodeError, status};
        }
        event_handler_->OnWithResponse(
            reinterpret_cast<::fidl::WireResponse<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    OnWithResponse>*>(msg->bytes));
        return std::nullopt;
      }
      default:
        break;
    }
  }
  FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
  return ::fidl::UnbindInfo{::fidl::UnbindInfo::kUnexpectedMessage,
                            ZX_ERR_NOT_SUPPORTED};
}
#endif  // __Fuchsia__

::fidl::Result fidl::WireSyncEventHandler<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    HandleOneEvent(::fidl::UnownedClientEnd<
                   ::fidl_test_protocols::WithAndWithoutRequestResponse>
                       client_end) {
  zx_status_t status = client_end.channel()->wait_one(
      ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, ::zx::time::infinite(),
      nullptr);
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorWaitOneFailed);
  }
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                OnEmptyResponse>::MaxNumHandles >= x) {
      x = ::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnEmptyResponse>::MaxNumHandles;
    }
    if (::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                OnWithResponse>::MaxNumHandles >= x) {
      x = ::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnWithResponse>::MaxNumHandles;
    }
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> read_storage;
  uint8_t* read_bytes = read_storage.data();
  zx_handle_info_t read_handles[kHandleAllocSize];
  uint32_t actual_bytes;
  uint32_t actual_handles;
  status = client_end.channel()->read_etc(
      ZX_CHANNEL_READ_MAY_DISCARD, read_bytes, read_handles,
      read_storage.size(), kHandleAllocSize, &actual_bytes, &actual_handles);
  if (status == ZX_ERR_BUFFER_TOO_SMALL) {
    // Message size is unexpectedly larger than calculated.
    // This can only be due to a newer version of the protocol defining a new
    // event, whose size exceeds the maximum of known events in the current
    // protocol.
    return ::fidl::Result(Unknown(), nullptr);
  }
  if (status != ZX_OK) {
    return ::fidl::Result(status, ::fidl::kErrorReadFailed);
  }
  if (actual_bytes < sizeof(fidl_message_header_t)) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(ZX_ERR_INVALID_ARGS, ::fidl::kErrorInvalidHeader);
  }
  fidl_message_header_t* hdr =
      reinterpret_cast<fidl_message_header_t*>(read_bytes);
  status = fidl_validate_txn_header(hdr);
  if (status != ZX_OK) {
    FidlHandleInfoCloseMany(read_handles, actual_handles);
    return ::fidl::Result(status, ::fidl::kErrorInvalidHeader);
  }
  switch (hdr->ordinal) {
    case ::fidl_test_protocols::
        kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  OnEmptyResponse>::Type,
          read_bytes, actual_bytes, read_handles, actual_handles,
          &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      OnEmptyResponse(reinterpret_cast<::fidl::WireResponse<
                          ::fidl_test_protocols::WithAndWithoutRequestResponse::
                              OnEmptyResponse>*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    case ::fidl_test_protocols::
        kWithAndWithoutRequestResponse_OnWithResponse_Ordinal: {
      const char* error_message;
      zx_status_t status = fidl_decode_etc(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  OnWithResponse>::Type,
          read_bytes, actual_bytes, read_handles, actual_handles,
          &error_message);
      if (status != ZX_OK) {
        return ::fidl::Result(status, error_message);
      }
      OnWithResponse(reinterpret_cast<::fidl::WireResponse<
                         ::fidl_test_protocols::WithAndWithoutRequestResponse::
                             OnWithResponse>*>(read_bytes));
      return ::fidl::Result(ZX_OK, nullptr);
    }
    default: {
      FidlHandleInfoCloseMany(read_handles, actual_handles);
      return ::fidl::Result(Unknown(), nullptr);
    }
  }
}

#ifdef __Fuchsia__

::fidl::DispatchResult fidl::internal::WireServerDispatcher<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    TryDispatch(::fidl::WireServer<
                    ::fidl_test_protocols::WithAndWithoutRequestResponse>* impl,
                fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestNoResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                NoRequestNoResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->NoRequestNoResponse(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestNoResponse>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestEmptyResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                NoRequestEmptyResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->NoRequestEmptyResponse(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestEmptyResponse>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestWithResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                NoRequestWithResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->NoRequestWithResponse(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestWithResponse>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestNoResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                WithRequestNoResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->WithRequestNoResponse(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestNoResponse>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestEmptyResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                WithRequestEmptyResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->WithRequestEmptyResponse(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestEmptyResponse>*>(bytes),
                    completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestWithResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                WithRequestWithResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->WithRequestWithResponse(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestWithResponse>*>(bytes),
                    completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

::fidl::DispatchResult fidl::internal::WireDispatcher<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::
    TryDispatch(::fidl::WireInterface<
                    ::fidl_test_protocols::WithAndWithoutRequestResponse>* impl,
                fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestNoResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                NoRequestNoResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->NoRequestNoResponse(completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestEmptyResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                NoRequestEmptyResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->NoRequestEmptyResponse(completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  NoRequestWithResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                NoRequestWithResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->NoRequestWithResponse(completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestNoResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    WithRequestNoResponse>*>(bytes);
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                WithRequestNoResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->WithRequestNoResponse(std::move(message->arg), completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestEmptyResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    WithRequestEmptyResponse>*>(bytes);
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                WithRequestEmptyResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->WithRequestEmptyResponse(std::move(message->arg), completer);
          },
      },
      {
          ::fidl_test_protocols::
              kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithAndWithoutRequestResponse::
                  WithRequestWithResponse>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            auto message = reinterpret_cast<::fidl::WireRequest<
                ::fidl_test_protocols::WithAndWithoutRequestResponse::
                    WithRequestWithResponse>*>(bytes);
            ::fidl::WireServer<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>::
                WithRequestWithResponseCompleter::Sync completer(txn);
            reinterpret_cast<::fidl::WireInterface<
                ::fidl_test_protocols::WithAndWithoutRequestResponse>*>(
                interface)
                ->WithRequestWithResponse(std::move(message->arg), completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestEmptyResponseCompleterBase::Reply() {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>>
      _response{};
  return ::fidl::WireServer<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>::
      NoRequestEmptyResponseCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestWithResponseCompleterBase::Reply(::fidl::StringView ret) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>>
      _response{ret};
  return ::fidl::WireServer<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>::
      NoRequestWithResponseCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    NoRequestWithResponseCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer, ::fidl::StringView ret) {
  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>::UnownedEncodedMessage
      _response(_backing_buffer.data, _backing_buffer.capacity, ret);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestEmptyResponseCompleterBase::Reply() {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>>
      _response{};
  return ::fidl::WireServer<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>::
      WithRequestEmptyResponseCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestWithResponseCompleterBase::Reply(::fidl::StringView ret) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>>
      _response{ret};
  return ::fidl::WireServer<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>::
      WithRequestWithResponseCompleterBase::SendReply(
          &_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result
fidl::WireServer<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    WithRequestWithResponseCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer, ::fidl::StringView ret) {
  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>::UnownedEncodedMessage
      _response(_backing_buffer.data, _backing_buffer.capacity, ret);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

void ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestEmptyResponse>::_InitHeader(zx_txid_t
                                                                      _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              NoRequestEmptyResponse>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestWithResponse>::_InitHeader(zx_txid_t
                                                                     _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              NoRequestWithResponse>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestNoResponse>::_InitHeader(zx_txid_t
                                                                     _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestEmptyResponse>::_InitHeader(zx_txid_t
                                                                        _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestEmptyResponse>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestWithResponse>::_InitHeader(zx_txid_t
                                                                       _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              WithRequestWithResponse>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              OnEmptyResponse>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal);
}

void ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                              OnWithResponse>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::
          kWithAndWithoutRequestResponse_OnWithResponse_Ordinal);
}

#ifdef __Fuchsia__

zx_status_t fidl::WireEventSender<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>::OnEmptyResponse()
    const {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::OnEmptyResponse>>
      _response{};
  _response.Write(server_end_);
  return _response.status();
}

zx_status_t
fidl::WireEventSender<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    OnWithResponse(::fidl::StringView ret) const {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::OnWithResponse>>
      _response{ret};
  _response.Write(server_end_);
  return _response.status();
}

zx_status_t
fidl::WireEventSender<::fidl_test_protocols::WithAndWithoutRequestResponse>::
    OnWithResponse(::fidl::BufferSpan _buffer, ::fidl::StringView ret) const {
  ::fidl::UnownedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::OnWithResponse>>
      _response(_buffer.data, _buffer.capacity, ret);
  _response.Write(server_end_);
  return _response.status();
}

#endif  // __Fuchsia__

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

namespace fidl_test_protocols {
[[maybe_unused]] constexpr uint64_t kWithErrorSyntax_ResponseAsStruct_Ordinal =
    4000554951765344912lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructResponseTable;

[[maybe_unused]] constexpr uint64_t kWithErrorSyntax_ErrorAsPrimitive_Ordinal =
    3421672554503271630lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveResponseTable;

[[maybe_unused]] constexpr uint64_t kWithErrorSyntax_ErrorAsEnum_Ordinal =
    627496610701472780lu;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumRequestTable;

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

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

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::
    WireResult(::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
                   _client) {
  ::fidl::OwnedEncodedMessage<::fidl::WireRequest<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

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

#ifdef __Fuchsia__
}  // namespace fidl_test_protocols
::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::
    WireResult(::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
                   _client) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>
      _request(zx_txid_t(0));
  _request.GetOutgoingMessage()
      .Call<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>(
          _client, bytes_.data(), bytes_.size());
  status_ = _request.status();
  error_ = _request.error();
}

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

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

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

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

#ifdef __Fuchsia__

::fidl::WireResponseContext<::fidl_test_protocols::WithErrorSyntax::
                                ResponseAsStruct>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::Type,
          ::fidl_test_protocols::kWithErrorSyntax_ResponseAsStruct_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::
    OnReply(uint8_t* reply) {
  OnReply(
      reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
                     response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::
                                 ResponseAsStruct>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::WithErrorSyntax>::ResponseAsStruct(
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
            _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithErrorSyntax>::ErrorAsPrimitive_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>(
            _channel->handle()));
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

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

#ifdef __Fuchsia__

::fidl::WireResponseContext<::fidl_test_protocols::WithErrorSyntax::
                                ErrorAsPrimitive>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::Type,
          ::fidl_test_protocols::kWithErrorSyntax_ErrorAsPrimitive_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::
    OnReply(uint8_t* reply) {
  OnReply(
      reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
                     response) override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::
                                 ErrorAsPrimitive>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::WithErrorSyntax>::ErrorAsPrimitive(
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
            _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

#ifdef __Fuchsia__
::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithErrorSyntax>::ErrorAsEnum_Sync() {
  if (auto _channel = ::fidl::internal::ClientBase::GetChannel()) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(
        ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>(
            _channel->handle()));
  }
  return ::fidl::WireResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(
      ::fidl::Result(ZX_ERR_CANCELED, ::fidl::kErrorChannelUnbound));
}
#endif  // __Fuchsia__

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

#ifdef __Fuchsia__

::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::WireResponseContext()
    : ::fidl::internal::ResponseContext(
          ::fidl::WireResponse<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::Type,
          ::fidl_test_protocols::kWithErrorSyntax_ErrorAsEnum_Ordinal) {}

void ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::OnReply(uint8_t*
                                                                      reply) {
  OnReply(reinterpret_cast<::fidl::WireResponse<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(reply));
}
#endif  // __Fuchsia__

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

    void OnReply(::fidl::WireResponse<
                 ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>* response)
        override {
      cb_(response);

      delete this;
    }

    void OnError() override { delete this; }

   private:
    ::fit::callback<void(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>* response)>
        cb_;
  };

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

::fidl::Result fidl::internal::
    WireClientImpl<::fidl_test_protocols::WithErrorSyntax>::ErrorAsEnum(
        ::fidl::WireResponseContext<
            ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>* _context) {
  ::fidl::internal::ClientBase::PrepareAsyncTxn(_context);

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

#ifdef __Fuchsia__
std::optional<::fidl::UnbindInfo> fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithErrorSyntax>::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_protocols::WithErrorSyntax>::TryDispatch(
        ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kWithErrorSyntax_ResponseAsStruct_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
                ResponseAsStructCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>*>(
                interface)
                ->ResponseAsStruct(reinterpret_cast<::fidl::WireRequest<
                                       ::fidl_test_protocols::WithErrorSyntax::
                                           ResponseAsStruct>*>(bytes),
                                   completer);
          },
      },
      {
          ::fidl_test_protocols::kWithErrorSyntax_ErrorAsPrimitive_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
                ErrorAsPrimitiveCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>*>(
                interface)
                ->ErrorAsPrimitive(reinterpret_cast<::fidl::WireRequest<
                                       ::fidl_test_protocols::WithErrorSyntax::
                                           ErrorAsPrimitive>*>(bytes),
                                   completer);
          },
      },
      {
          ::fidl_test_protocols::kWithErrorSyntax_ErrorAsEnum_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
                ErrorAsEnumCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>*>(
                interface)
                ->ErrorAsEnum(
                    reinterpret_cast<::fidl::WireRequest<
                        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(
                        bytes),
                    completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

::fidl::DispatchResult fidl::internal::
    WireDispatcher<::fidl_test_protocols::WithErrorSyntax>::TryDispatch(
        ::fidl::WireInterface<::fidl_test_protocols::WithErrorSyntax>* impl,
        fidl_incoming_msg_t* msg, ::fidl::Transaction* txn) {
  static const ::fidl::internal::MethodEntry entries[] = {
      {
          ::fidl_test_protocols::kWithErrorSyntax_ResponseAsStruct_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
                ResponseAsStructCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::WithErrorSyntax>*>(
                interface)
                ->ResponseAsStruct(completer);
          },
      },
      {
          ::fidl_test_protocols::kWithErrorSyntax_ErrorAsPrimitive_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
                ErrorAsPrimitiveCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::WithErrorSyntax>*>(
                interface)
                ->ErrorAsPrimitive(completer);
          },
      },
      {
          ::fidl_test_protocols::kWithErrorSyntax_ErrorAsEnum_Ordinal,
          ::fidl::WireRequest<
              ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::Type,
          [](void* interface, void* bytes, ::fidl::Transaction* txn) {
            ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
                ErrorAsEnumCompleter::Sync completer(txn);
            reinterpret_cast<
                ::fidl::WireInterface<::fidl_test_protocols::WithErrorSyntax>*>(
                interface)
                ->ErrorAsEnum(completer);
          },
      },
  };
  return ::fidl::internal::TryDispatch(
      impl, msg, txn, entries,
      entries + sizeof(entries) / sizeof(::fidl::internal::MethodEntry));
}

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

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ResponseAsStructCompleterBase::Reply(
        ::fidl_test_protocols::wire::WithErrorSyntaxResponseAsStructResult
            result) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>
      _response{result};
  return ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
      ResponseAsStructCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ResponseAsStructCompleterBase::ReplySuccess(int64_t a, int64_t b,
                                                int64_t c) {
  ::fidl_test_protocols::wire::WithErrorSyntaxResponseAsStructResponse
      _response;
  _response.a = std::move(a);
  _response.b = std::move(b);
  _response.c = std::move(c);

  return Reply(
      ::fidl_test_protocols::wire::WithErrorSyntaxResponseAsStructResult::
          WithResponse(
              ::fidl::ObjectView<::fidl_test_protocols::wire::
                                     WithErrorSyntaxResponseAsStructResponse>::
                  FromExternal(&_response)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ResponseAsStructCompleterBase::ReplyError(uint32_t error) {
  return Reply(
      ::fidl_test_protocols::wire::WithErrorSyntaxResponseAsStructResult::
          WithErr(::fidl::ObjectView<uint32_t>::FromExternal(&error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ResponseAsStructCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer,
        ::fidl_test_protocols::wire::WithErrorSyntaxResponseAsStructResult
            result) {
  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ResponseAsStructCompleterBase::ReplySuccess(::fidl::BufferSpan _buffer,
                                                int64_t a, int64_t b,
                                                int64_t c) {
  ::fidl_test_protocols::wire::WithErrorSyntaxResponseAsStructResponse response;
  response.a = std::move(a);
  response.b = std::move(b);
  response.c = std::move(c);

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

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsPrimitiveCompleterBase::Reply(
        ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResult
            result) {
  ::fidl::OwnedEncodedMessage<::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>
      _response{result};
  return ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
      ErrorAsPrimitiveCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsPrimitiveCompleterBase::ReplySuccess() {
  ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResponse
      _response;

  return Reply(
      ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResult::
          WithResponse(
              ::fidl::ObjectView<::fidl_test_protocols::wire::
                                     WithErrorSyntaxErrorAsPrimitiveResponse>::
                  FromExternal(&_response)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsPrimitiveCompleterBase::ReplyError(uint32_t error) {
  return Reply(
      ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResult::
          WithErr(::fidl::ObjectView<uint32_t>::FromExternal(&error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsPrimitiveCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer,
        ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResult
            result) {
  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsPrimitiveCompleterBase::ReplySuccess(::fidl::BufferSpan _buffer) {
  ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResponse response;

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

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsEnumCompleterBase::Reply(
        ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsEnumResult result) {
  ::fidl::OwnedEncodedMessage<
      ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>
      _response{result};
  return ::fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
      ErrorAsEnumCompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsEnumCompleterBase::ReplySuccess() {
  ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsEnumResponse _response;

  return Reply(
      ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsEnumResult::
          WithResponse(
              ::fidl::ObjectView<::fidl_test_protocols::wire::
                                     WithErrorSyntaxErrorAsEnumResponse>::
                  FromExternal(&_response)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsEnumCompleterBase::ReplyError(
        ::fidl_test_protocols::wire::ErrorEnun error) {
  return Reply(
      ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsEnumResult::WithErr(
          ::fidl::ObjectView<
              ::fidl_test_protocols::wire::ErrorEnun>::FromExternal(&error)));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsEnumCompleterBase::Reply(
        ::fidl::BufferSpan _backing_buffer,
        ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsEnumResult result) {
  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::
      UnownedEncodedMessage _response(_backing_buffer.data,
                                      _backing_buffer.capacity, result);
  return CompleterBase::SendReply(&_response.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
::fidl::Result fidl::WireServer<::fidl_test_protocols::WithErrorSyntax>::
    ErrorAsEnumCompleterBase::ReplySuccess(::fidl::BufferSpan _buffer) {
  ::fidl_test_protocols::wire::WithErrorSyntaxErrorAsEnumResponse response;

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

void ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::
                             ResponseAsStruct>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::kWithErrorSyntax_ResponseAsStruct_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::kWithErrorSyntax_ResponseAsStruct_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::
                             ErrorAsPrimitive>::_InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::kWithErrorSyntax_ErrorAsPrimitive_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0,
      ::fidl_test_protocols::kWithErrorSyntax_ErrorAsPrimitive_Ordinal);
}

void ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::
    _InitHeader(zx_txid_t _txid) {
  fidl_init_txn_header(
      &_hdr, _txid,
      ::fidl_test_protocols::kWithErrorSyntax_ErrorAsEnum_Ordinal);
}

void ::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::_InitHeader() {
  fidl_init_txn_header(
      &_hdr, 0, ::fidl_test_protocols::kWithErrorSyntax_ErrorAsEnum_Ordinal);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
