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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.driveroneway/cpp/markers.h>
#include <fidl/test.driveroneway/cpp/wire_types.h>
#include <lib/fidl_driver/cpp/wire_messaging.h>

#ifdef __Fuchsia__

#include <lib/fidl/cpp/wire/connect_service.h>
#include <lib/fidl/cpp/wire/server.h>
#include <lib/fidl/cpp/wire/service_handler.h>
#include <lib/fidl/cpp/wire/sync_call.h>
#include <lib/fidl_driver/cpp/server.h>
#include <lib/fidl_driver/cpp/wire_client.h>

#endif  // __Fuchsia__

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_driveroneway {

class OneWay;

}  // namespace test_driveroneway

template <>
struct ::fidl::internal::WireOrdinal<::test_driveroneway::OneWay::Send> final {
  static constexpr uint64_t value = 7942965975761529343lu;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<::test_driveroneway::OneWay::Send> {
  static constexpr bool HasRequestPayload = true;
  using Request = ::test_driveroneway::wire::OneWaySendRequest;

  using Completer = fidl::Completer<>;
};

#endif  // __Fuchsia__

namespace test_driveroneway {

}  // namespace test_driveroneway

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_driveroneway::OneWay> {
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_driveroneway::OneWay> final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(::fdf::WireServer<::test_driveroneway::OneWay>* impl, ::fidl::IncomingHeaderAndMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch(::fdf::WireServer<::test_driveroneway::OneWay>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct ::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send> final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::test_driveroneway::wire::OneWaySendRequest body;
  explicit TransactionalRequest(const ::test_driveroneway::wire::Payload& payload)
      : body(::test_driveroneway::wire::OneWaySendRequest{payload}) {
    _InitHeader();
  }
  TransactionalRequest() {
    _InitHeader();
  }

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 4 + sizeof(fidl_message_header_t);

  static void Encode(internal::WireEncoder* encoder, ::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<fidl_message_header_t>() = value->header;
    WireCodingTraits<::test_driveroneway::wire::OneWaySendRequest, WireCodingConstraintEmpty, IsRecursive>::Encode(
        encoder, &value->body, position + sizeof(fidl_message_header_t), recursion_depth);
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    WireCodingTraits<::test_driveroneway::wire::OneWaySendRequest, WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + sizeof(fidl_message_header_t), recursion_depth);
  }
};

#endif  // __Fuchsia__

namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>> : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(sizeof(::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>) == TypeTraits<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>, header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>, body) == sizeof(fidl_message_header_t));
static_assert(sizeof(::test_driveroneway::wire::OneWaySendRequest) == TypeTraits<::test_driveroneway::wire::OneWaySendRequest>::kPrimarySize);
static_assert(offsetof(::test_driveroneway::wire::OneWaySendRequest, payload) == 0);

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class [[nodiscard]] ::fdf::WireUnownedResult<::test_driveroneway::OneWay::Send> final : public ::fidl::BaseWireResult<::test_driveroneway::OneWay::Send> {
 public:
  explicit WireUnownedResult(::fdf::UnownedClientEnd<::test_driveroneway::OneWay> client_end, const ::fdf::Arena& arena, ::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>* request);
  explicit WireUnownedResult(
      ::fit::result<::fidl::Error>&& decoded,
      ::fidl::internal::MessageStorageViewBase* storage_view) : ::fidl::BaseWireResult<::test_driveroneway::OneWay::Send>(::fidl::internal::StatusFromResult(decoded)) {}

  explicit WireUnownedResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_driveroneway::OneWay::Send>(result) {}
  WireUnownedResult(WireUnownedResult&&) = default;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult& operator=(WireUnownedResult&&) = default;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

template <>
class ::fidl::internal::WireEventHandlerInterface<::test_driveroneway::OneWay> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fdf::WireAsyncEventHandler<::test_driveroneway::OneWay>
    : public ::fidl::internal::WireEventHandlerInterface<::test_driveroneway::OneWay>, public ::fidl::internal::AsyncEventHandler {
 public:
  WireAsyncEventHandler() = default;
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_driveroneway::OneWay> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::WireEventHandlerInterface<::test_driveroneway::OneWay>> {
 public:
  explicit WireEventDispatcher(::fidl::internal::WireEventHandlerInterface<::test_driveroneway::OneWay>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

template <>
class ::fidl::internal::WireSyncBufferClientImpl<::test_driveroneway::OneWay> final : public ::fdf::internal::SyncEndpointBufferVeneer<::fidl::internal::WireSyncBufferClientImpl<::test_driveroneway::OneWay>> {
 public:
  // Caller provides the backing storage for FIDL message via an argument to `.buffer()`.
  ::fidl::OneWayStatus
  Send(const ::test_driveroneway::wire::Payload& payload) {
    ::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send> _request{payload};
    return ::fdf::WireUnownedResult<::test_driveroneway::OneWay::Send>(_client_end(), _arena(), &_request);
  }

 private:
  ::fdf::UnownedClientEnd<::test_driveroneway::OneWay> _client_end() const {
    return ::fdf::UnownedClientEnd<::test_driveroneway::OneWay>(
        _transport().get<::fidl::internal::DriverTransport>());
  }
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |::fdf::ClientEnd<::test_driveroneway::OneWay>|
// and |::fdf::ServerEnd<::test_driveroneway::OneWay>|).
template <>
class ::fdf::WireServer<::test_driveroneway::OneWay> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_driveroneway::OneWay;

  using Handler = fidl::ProtocolHandler<::test_driveroneway::OneWay>;

  using SendCompleter = ::fidl::internal::WireCompleter<::test_driveroneway::OneWay::Send>;
  using SendRequestView = ::test_driveroneway::wire::OneWaySendRequest*;

  virtual void Send(
      ::test_driveroneway::wire::OneWaySendRequest* request,
      fdf::Arena& arena,
      SendCompleter::Sync& completer) = 0;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(fdf_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fdf::ServerEnd<::test_driveroneway::OneWay> request) {
      (void)::fdf::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};
namespace fidl {

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_driveroneway::OneWay> : public ::fdf::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;

  // Caller provides the backing storage for FIDL message.
  ::fidl::OneWayStatus Send(const ::test_driveroneway::wire::Payload& payload);
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<::test_driveroneway::OneWay> final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_driveroneway::OneWay> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_driveroneway::OneWay> : public ::fidl::internal::ClientImplBase {
 public:
  WireWeakOnewayClientImpl(fidl::internal::ClientBase* client_base, const fdf::Arena& arena)
      : ClientImplBase(client_base), arena_(arena) {}

  // Allocates 40 bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::OneWayStatus Send(const ::test_driveroneway::wire::Payload& payload);

 protected:
  const ::fdf::Arena& arena_;
};

template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_driveroneway::OneWay> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_driveroneway::OneWay> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};
namespace fidl {

#endif  // __Fuchsia__

}  // namespace fidl

#ifdef __Fuchsia__
template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_driveroneway::OneWay> : public ::fdf::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_driveroneway::OneWay>
    : public ::fdf::internal::SyncEndpointBufferVeneer<::fidl::internal::WireBufferEventSender<::test_driveroneway::OneWay>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop
