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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.drivertwoway/cpp/driver/wire_messaging.h>
#include <fidl/test.drivertwoway/cpp/markers.h>
#include <fidl/test.drivertwoway/cpp/natural_types.h>
#include <lib/fidl_driver/cpp/natural_messaging.h>

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

#ifdef __Fuchsia__

#endif  // __Fuchsia__

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_drivertwoway::TwoWay::Add> {
  using Request = ::test_drivertwoway::TwoWayAddRequest;

  using Response = ::test_drivertwoway::TwoWayAddResponse;

  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<::test_drivertwoway::TwoWay::Add>>;
  using ResultCallback =
      ::fit::callback<void(::fdf::Result<::test_drivertwoway::TwoWay::Add>&)>;
};
#ifdef __Fuchsia__

template <>
class ::fidl::Response<::test_drivertwoway::TwoWay::Add> final : public ::test_drivertwoway::TwoWayAddResponse {
 public:
  using ::test_drivertwoway::TwoWayAddResponse::TwoWayAddResponse;
  Response(::test_drivertwoway::TwoWayAddResponse v) : TwoWayAddResponse(std::move(v)) {}
};

template <>
class ::fdf::Result<::test_drivertwoway::TwoWay::Add> final : public ::fit::result<::fidl::Error, ::test_drivertwoway::TwoWayAddResponse> {
 public:
  using ::fit::result<::fidl::Error, ::test_drivertwoway::TwoWayAddResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::internal::NaturalClientImpl<::test_drivertwoway::TwoWay> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fidl::internal::NaturalThenable<::test_drivertwoway::TwoWay::Add> Add(const ::fidl::Request<::test_drivertwoway::TwoWay::Add>& request) const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

template <>
class ::fdf::AsyncEventHandler<::test_drivertwoway::TwoWay>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_drivertwoway::TwoWay>, public ::fidl::internal::AsyncEventHandler {
 public:
  AsyncEventHandler() = default;
};

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

#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<::test_drivertwoway::TwoWay::Add> : public ::fidl::CompleterBase {
 public:
  void Reply(const ::fidl::Response<::test_drivertwoway::TwoWay::Add>& response);

 protected:
  using ::fidl::CompleterBase::CompleterBase;
};

template <>
class ::fdf::Server<::test_drivertwoway::TwoWay> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  Server() = default;
  virtual ~Server() = default;

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

  using Handler = fidl::ProtocolHandler<::test_drivertwoway::TwoWay>;

  using AddRequest = ::fidl::Request<::test_drivertwoway::TwoWay::Add>;
  using AddCompleter = ::fidl::internal::NaturalCompleter<::test_drivertwoway::TwoWay::Add>;

  virtual void Add(AddRequest& request,
                   AddCompleter::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_drivertwoway::TwoWay> 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;
};
#ifdef __Fuchsia__

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