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

#include <fidl/test.handles/cpp/wire_messaging.h>

#include <memory>

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status
fidl::WireSyncEventHandler<::test_handles::SomeProtocol>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_handles::SomeProtocol> 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::Status::TransportError(
        status, ::fidl::internal::kErrorWaitOneFailed);
  }
  constexpr uint32_t kHandleAllocSize = ([]() constexpr {
    uint32_t x = 0;
    if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
      x = ZX_CHANNEL_MAX_MSG_HANDLES;
    }
    return x;
  })();
  static_assert(kHandleAllocSize <= ZX_CHANNEL_MAX_MSG_HANDLES);
  ::fidl::internal::InlineMessageBuffer<16> read_storage;
  std::array<zx_handle_t, kHandleAllocSize> read_handles;
  // TODO(fxbug.dev/85734) Remove this channel-specific allocation.
  std::array<fidl_channel_handle_metadata_t, kHandleAllocSize>
      read_handle_metadata;
  ::fidl::IncomingMessage msg = ::fidl::MessageRead(
      zx::unowned_channel(client_end.handle()), read_storage.view(),
      read_handles.data(), read_handle_metadata.data(), kHandleAllocSize,
      ReadOptions{.discardable = true});
  if (msg.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::Status::UnexpectedMessage(
        ZX_ERR_BUFFER_TOO_SMALL,
        ::fidl::internal::kErrorSyncEventBufferTooSmall);
  }
  if (!msg.ok()) {
    return msg;
  }
  fidl_message_header_t* hdr = msg.header();
  switch (hdr->ordinal) {
    default: {
      return ::fidl::Status::UnknownOrdinal();
    }
  }
}

std::optional<::fidl::UnbindInfo> fidl::internal::
    WireEventDispatcher<::test_handles::SomeProtocol>::DispatchEvent(
        ::fidl::IncomingMessage& msg,
        ::fidl::internal::IncomingTransportContext transport_context) {
  switch (msg.header()->ordinal) {
    default:
      break;
  }
  return ::fidl::UnbindInfo::UnknownOrdinal();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::WireServerDispatcher<
    ::test_handles::SomeProtocol>::entries_[] = {};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<
    ::test_handles::SomeProtocol>::entries_end_ = &entries_[0];

::fidl::DispatchResult
fidl::internal::WireServerDispatcher<::test_handles::SomeProtocol>::TryDispatch(
    ::fidl::WireServer<::test_handles::SomeProtocol>* impl,
    ::fidl::IncomingMessage& msg,
    internal::IncomingTransportContext transport_context,
    ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(impl, msg, std::move(transport_context),
                                       txn, entries_, entries_end_);
}

void fidl::internal::WireServerDispatcher<::test_handles::SomeProtocol>::
    Dispatch(::fidl::WireServer<::test_handles::SomeProtocol>* impl,
             ::fidl::IncomingMessage&& msg,
             internal::IncomingTransportContext transport_context,
             ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, std::move(transport_context), txn,
                             entries_, entries_end_);
}
void fidl::WireServer<::test_handles::SomeProtocol>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::IncomingTransportContext transport_context) {
  ::fidl::internal::WireServerDispatcher<
      ::test_handles::SomeProtocol>::Dispatch(this, std::move(msg),
                                              std::move(transport_context),
                                              txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
