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

#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>

#ifdef __Fuchsia__

#endif  // __Fuchsia__

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_drivertwoway::TwoWay::Add> {
  using Completer = fidl::Completer<
      ::fidl::internal::NaturalCompleterBase<::test_drivertwoway::TwoWay::Add>>;

  using ResultCallback =
      ::fit::callback<void(::fdf::Result<::test_drivertwoway::TwoWay::Add>&)>;

  static constexpr bool HasApplicationError = false;

  static constexpr bool IsAbsentBody = false;
};
namespace test_drivertwoway {
__LOCAL extern "C" const fidl_type_t test_drivertwoway_TwoWayAddRequestTable;
__LOCAL extern "C" const fidl_type_t
    test_drivertwoway_TwoWayAddTopResponseTable;
#ifdef __Fuchsia__
}  // namespace test_drivertwoway

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

template <>
struct ::fidl::internal::MessageTraits<
    ::fidl::Response<::test_drivertwoway::TwoWay::Add>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_drivertwoway::TwoWayAddTopResponse;
};
namespace test_drivertwoway {}  // namespace test_drivertwoway
template <>
class ::fdf::Result<::test_drivertwoway::TwoWay::Add> final
    : public ::fitx::result<::fidl::Error,
                            ::test_drivertwoway::TwoWayAddTopResponse> {
 public:
  using ::fitx::result<::fidl::Error,
                       ::test_drivertwoway::TwoWayAddTopResponse>::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(
      ::fidl::Request<::test_drivertwoway::TwoWay::Add> request) const;
};
namespace test_drivertwoway {
#endif  // __Fuchsia__
}  // namespace test_drivertwoway
#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<
    ::test_drivertwoway::TwoWay> {
 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<
                ::fdf::AsyncEventHandler<::test_drivertwoway::TwoWay>> {
 public:
  explicit NaturalEventDispatcher(
      ::fdf::AsyncEventHandler<::test_drivertwoway::TwoWay>* event_handler)
      : IncomingEventDispatcher(event_handler) {}

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

#ifdef __Fuchsia__

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

template <>
struct ::fidl::internal::MessageTraits<
    ::fidl::Request<::test_drivertwoway::TwoWay::Add>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_drivertwoway::TwoWayAddRequest;
};
#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<::test_drivertwoway::TwoWay::Add>
    : public ::fidl::CompleterBase {
 public:
  void Reply(::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 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;

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};
#ifdef __Fuchsia__

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