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

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

#include <memory>

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status
fidl::WireSyncEventHandler<::test_versions::OtherProtocol>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_versions::OtherProtocol> 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_versions::OtherProtocol>::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_versions::OtherProtocol>::entries_[] = {};

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

::fidl::DispatchResult fidl::internal::
    WireServerDispatcher<::test_versions::OtherProtocol>::TryDispatch(
        ::fidl::WireServer<::test_versions::OtherProtocol>* 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_versions::OtherProtocol>::
    Dispatch(::fidl::WireServer<::test_versions::OtherProtocol>* 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_versions::OtherProtocol>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::IncomingTransportContext transport_context) {
  ::fidl::internal::WireServerDispatcher<
      ::test_versions::OtherProtocol>::Dispatch(this, std::move(msg),
                                                std::move(transport_context),
                                                txn);
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

namespace test_versions {
[[maybe_unused]] constexpr uint64_t kProtocol_Foo_Ordinal =
    6231434419097198905lu;

[[maybe_unused]] constexpr ::fidl::MessageDynamicFlags
    kProtocol_Foo_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
#ifdef __Fuchsia__
}  // namespace test_versions
::fidl::WireResult<::test_versions::Protocol::Foo>::WireResult(
    ::fidl::UnownedClientEnd<::test_versions::Protocol> client,
    ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>*
        request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>,
      ::fidl::internal::ChannelTransport>
      request_message(::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client.handle());
  SetStatus(outgoing);
}
namespace test_versions {
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_versions
::fidl::WireUnownedResult<::test_versions::Protocol::Foo>::WireUnownedResult(
    ::fidl::UnownedClientEnd<::test_versions::Protocol> client_end,
    ::fidl::internal::AnyBufferAllocator& allocator,
    ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>*
        request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<
      ::test_versions::Protocol::Foo>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation =
      allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;

  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>>
      request_message(request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Write(client_end.handle());
  ::fidl::Status::operator=(outgoing);
}
namespace test_versions {
#endif  // __Fuchsia__

}  // namespace test_versions
#ifdef __Fuchsia__

::fidl::Status
fidl::internal::WireWeakOnewayClientImpl<::test_versions::Protocol>::Foo() {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>
      _request_object{};
  ::fidl::unstable::OwnedEncodedMessage<
      ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>,
      ::fidl::internal::ChannelTransport>
      _request_message(::fidl::internal::AllowUnownedInputRef{},
                       &_request_object);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
::fidl::Status fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_versions::Protocol>::Foo() {
  constexpr uint32_t _buffer_size =
      ::fidl::AsyncClientMethodBufferSizeInChannel<
          ::test_versions::Protocol::Foo>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    return _allocation.error_value();
  }

  ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>
      _request{};
  ::fidl::unstable::UnownedEncodedMessage<
      ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>>
      _request_message(_allocation->data, _buffer_size, &_request);
  return _client_base()->SendOneWay(_request_message.GetOutgoingMessage());
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status
fidl::WireSyncEventHandler<::test_versions::Protocol>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_versions::Protocol> 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_versions::Protocol>::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_versions::Protocol>::entries_[] = {
    {
        ::test_versions::kProtocol_Foo_Ordinal,
        [](void* interface, ::fidl::IncomingMessage&& msg,
           internal::IncomingTransportContext transport_context,
           ::fidl::Transaction* txn) {
          ::fidl::WireRequest<::test_versions::Protocol::Foo> empty_request;
          auto* primary = &empty_request;
          ::fidl::internal::WireCompleter<::test_versions::Protocol::Foo>::Sync
              completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_versions::Protocol>*>(
              interface)
              ->Foo(primary, completer);
          return ZX_OK;
        },
    },
};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<
    ::test_versions::Protocol>::entries_end_ = &entries_[1];

::fidl::DispatchResult
fidl::internal::WireServerDispatcher<::test_versions::Protocol>::TryDispatch(
    ::fidl::WireServer<::test_versions::Protocol>* 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_versions::Protocol>::Dispatch(
    ::fidl::WireServer<::test_versions::Protocol>* 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_versions::Protocol>::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::IncomingTransportContext transport_context) {
  ::fidl::internal::WireServerDispatcher<::test_versions::Protocol>::Dispatch(
      this, std::move(msg), std::move(transport_context), txn);
}
#endif  // __Fuchsia__

void ::fidl::internal::TransactionalRequest<
    ::test_versions::Protocol::Foo>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_versions::kProtocol_Foo_Ordinal,
                        ::test_versions::kProtocol_Foo_DynamicFlags);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__
