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

#pragma once

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

#ifdef __Fuchsia__

#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl_driver/cpp/server.h>
#include <lib/fidl_driver/cpp/wire_client.h>

#endif  // __Fuchsia__

#include <fidl/fdf/cpp/driver/wire_messaging.h>

namespace test_handles {
class DriverProtocol;

}  // namespace test_handles
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_handles::DriverProtocol> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_handles::DriverProtocol>
    final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fdf::WireServer<::test_handles::DriverProtocol>* impl,
      ::fidl::IncomingMessage& msg,
      internal::IncomingTransportContext transport_context,
      ::fidl::Transaction* txn);
  static void Dispatch(::fdf::WireServer<::test_handles::DriverProtocol>* impl,
                       ::fidl::IncomingMessage&& msg,
                       internal::IncomingTransportContext transport_context,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
#endif  // __Fuchsia__

namespace fidl {}  // namespace fidl
namespace test_handles {
#ifdef __Fuchsia__
}  // namespace test_handles
template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::test_handles::DriverProtocol> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

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

template <>
class ::fidl::WireSyncEventHandler<::test_handles::DriverProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::test_handles::DriverProtocol> {
 public:
  WireSyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Status HandleOneEvent(
      ::fdf::UnownedClientEnd<::test_handles::DriverProtocol> client_end);

 private:
  [[maybe_unused]] bool got_transitional_ = false;
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_handles::DriverProtocol>
    final : public ::fidl::internal::IncomingEventDispatcher<
                ::fdf::WireAsyncEventHandler<::test_handles::DriverProtocol>> {
 public:
  explicit WireEventDispatcher(
      ::fdf::WireAsyncEventHandler<::test_handles::DriverProtocol>*
          event_handler)
      : IncomingEventDispatcher(event_handler) {}

 private:
  std::optional<::fidl::UnbindInfo> DispatchEvent(
      ::fidl::IncomingMessage& msg,
      ::fidl::internal::IncomingTransportContext transport_context) override;
};

template <>
class ::fidl::internal::WireSyncBufferClientImpl<::test_handles::DriverProtocol>
    final : public ::fdf::internal::SyncEndpointBufferVeneer<
                ::fidl::internal::WireSyncBufferClientImpl<
                    ::test_handles::DriverProtocol>> {
 public:
 private:
  ::fdf::UnownedClientEnd<::test_handles::DriverProtocol> _client_end() const {
    return ::fdf::UnownedClientEnd<::test_handles::DriverProtocol>(
        _transport().get<::fidl::internal::DriverTransport>());
  }
};

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

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

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};
namespace test_handles {
#endif  // __Fuchsia__

}  // namespace test_handles
namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_handles::DriverProtocol>
    : public ::fdf::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_handles::DriverProtocol>
    final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<
                ::test_handles::DriverProtocol> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;
};

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

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

template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_handles::DriverProtocol>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_handles::DriverProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
