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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.service/cpp/markers.h>
#include <fidl/test.service/cpp/natural_types.h>
#include <fidl/test.service/cpp/wire_messaging.h>
#include <lib/fidl/cpp/channel.h>
#include <lib/fidl/cpp/client.h>
#include <lib/fidl/cpp/internal/thenable.h>
#include <lib/fidl/cpp/natural_types.h>
#include <lib/fidl/cpp/unified_messaging.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>

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

namespace fidl {

}  // namespace fidl

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_service::FirstProtocol::MethodOnFirst> {
  using Completer = fidl::Completer<>;
};

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalClientImpl<::test_service::FirstProtocol> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fit::result<::fidl::OneWayError> MethodOnFirst() const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_service::FirstProtocol> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_service::FirstProtocol>> {
 public:
  ::fit::result<::fidl::OneWayError> MethodOnFirst();

 private:
  ::fidl::UnownedClientEnd<::test_service::FirstProtocol> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_service::FirstProtocol>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_service::FirstProtocol> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  NaturalEventHandlerInterface() = default;
  virtual ~NaturalEventHandlerInterface() = default;
};

template <>
class ::fidl::AsyncEventHandler<::test_service::FirstProtocol>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_service::FirstProtocol>, public ::fidl::internal::AsyncEventHandler {
 public:
  AsyncEventHandler() = default;
};

template <>
class ::fidl::SyncEventHandler<::test_service::FirstProtocol>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_service::FirstProtocol>, public ::fidl::internal::SyncEventHandler {
 public:
  SyncEventHandler() = 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(
      ::fidl::UnownedClientEnd<::test_service::FirstProtocol> client_end);
};

template <>
class ::fidl::internal::NaturalEventDispatcher<::test_service::FirstProtocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::NaturalEventHandlerInterface<::test_service::FirstProtocol>> {
 public:
  explicit NaturalEventDispatcher(::fidl::internal::NaturalEventHandlerInterface<::test_service::FirstProtocol>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
class ::fidl::internal::NaturalWeakEventSender<::test_service::FirstProtocol> : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::NaturalEventSender<::test_service::FirstProtocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalEventSender<::test_service::FirstProtocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

#endif  // __Fuchsia__

template <>
class ::fidl::Server<::test_service::FirstProtocol> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  Server() = default;
  virtual ~Server() = default;

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

  using Handler = fidl::ProtocolHandler<::test_service::FirstProtocol>;

  using MethodOnFirstCompleter = ::fidl::internal::NaturalCompleter<::test_service::FirstProtocol::MethodOnFirst>;

  virtual void MethodOnFirst(
      MethodOnFirstCompleter::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(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_service::FirstProtocol> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

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

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<::test_service::FirstProtocol> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_service::FirstProtocol>* 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__

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_service::SecondProtocol::MethodOnSecond> {
  using Completer = fidl::Completer<>;
};

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalClientImpl<::test_service::SecondProtocol> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fit::result<::fidl::OneWayError> MethodOnSecond() const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_service::SecondProtocol> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_service::SecondProtocol>> {
 public:
  ::fit::result<::fidl::OneWayError> MethodOnSecond();

 private:
  ::fidl::UnownedClientEnd<::test_service::SecondProtocol> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_service::SecondProtocol>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_service::SecondProtocol> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  NaturalEventHandlerInterface() = default;
  virtual ~NaturalEventHandlerInterface() = default;
};

template <>
class ::fidl::AsyncEventHandler<::test_service::SecondProtocol>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_service::SecondProtocol>, public ::fidl::internal::AsyncEventHandler {
 public:
  AsyncEventHandler() = default;
};

template <>
class ::fidl::SyncEventHandler<::test_service::SecondProtocol>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_service::SecondProtocol>, public ::fidl::internal::SyncEventHandler {
 public:
  SyncEventHandler() = 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(
      ::fidl::UnownedClientEnd<::test_service::SecondProtocol> client_end);
};

template <>
class ::fidl::internal::NaturalEventDispatcher<::test_service::SecondProtocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::NaturalEventHandlerInterface<::test_service::SecondProtocol>> {
 public:
  explicit NaturalEventDispatcher(::fidl::internal::NaturalEventHandlerInterface<::test_service::SecondProtocol>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
class ::fidl::internal::NaturalWeakEventSender<::test_service::SecondProtocol> : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::NaturalEventSender<::test_service::SecondProtocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalEventSender<::test_service::SecondProtocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

#endif  // __Fuchsia__

template <>
class ::fidl::Server<::test_service::SecondProtocol> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  Server() = default;
  virtual ~Server() = default;

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

  using Handler = fidl::ProtocolHandler<::test_service::SecondProtocol>;

  using MethodOnSecondCompleter = ::fidl::internal::NaturalCompleter<::test_service::SecondProtocol::MethodOnSecond>;

  virtual void MethodOnSecond(
      MethodOnSecondCompleter::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(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_service::SecondProtocol> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

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

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<::test_service::SecondProtocol> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_service::SecondProtocol>* 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__

#pragma clang diagnostic pop
