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

#pragma once

#include "lib/fidl/cpp/internal/header.h"

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace service {
#ifdef __Fuchsia__

class SecondProtocol;
using SecondProtocolHandle = ::fidl::InterfaceHandle<SecondProtocol>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class FirstProtocol;
using FirstProtocolHandle = ::fidl::InterfaceHandle<FirstProtocol>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class SingleMemberService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHomogeneousMemberService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHeterogeneousMemberService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class EmptyService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_service_SecondProtocolMethodOnSecondRequestTable;

}  // namespace _internal
class SecondProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage MethodOnSecond(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(DidHLCPPEncode,
               &::fidl::test::service::_internal::
                   fidl_test_service_SecondProtocolMethodOnSecondRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

class SecondProtocol_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_service_FirstProtocolMethodOnFirstRequestTable;

}  // namespace _internal
class FirstProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage MethodOnFirst(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(DidHLCPPEncode,
               &::fidl::test::service::_internal::
                   fidl_test_service_FirstProtocolMethodOnFirstRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

class FirstProtocol_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

}  // namespace service
}  // namespace test

//
// Proxies and stubs declarations
//
namespace test {
namespace service {
#ifdef __Fuchsia__

using SecondProtocolPtr = ::fidl::InterfacePtr<SecondProtocol>;
class SecondProtocol_Proxy;
class SecondProtocol_Stub;
class SecondProtocol_EventSender;
class SecondProtocol_Sync;
using SecondProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<SecondProtocol>;
class SecondProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kSecondProtocol_MethodOnSecond_Ordinal =
    0x54ea6448c1555a29lu;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using FirstProtocolPtr = ::fidl::InterfacePtr<FirstProtocol>;
class FirstProtocol_Proxy;
class FirstProtocol_Stub;
class FirstProtocol_EventSender;
class FirstProtocol_Sync;
using FirstProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<FirstProtocol>;
class FirstProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kFirstProtocol_MethodOnFirst_Ordinal = 0x5b76bb4db7c2bba4lu;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class SingleMemberService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHomogeneousMemberService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHeterogeneousMemberService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__
class EmptyService;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class SecondProtocol {
 public:
  using Proxy_ = ::fidl::test::service::SecondProtocol_Proxy;
  using Stub_ = ::fidl::test::service::SecondProtocol_Stub;
  using EventSender_ = ::fidl::test::service::SecondProtocol_EventSender;
  using Sync_ = ::fidl::test::service::SecondProtocol_Sync;
  virtual ~SecondProtocol();

  virtual void MethodOnSecond() = 0;
};

class SecondProtocol_RequestDecoder {
 public:
  SecondProtocol_RequestDecoder() = default;
  virtual ~SecondProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void MethodOnSecond() = 0;
};

class SecondProtocol_ResponseDecoder {
 public:
  SecondProtocol_ResponseDecoder() = default;
  virtual ~SecondProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

class SecondProtocol_EventSender {
 public:
  virtual ~SecondProtocol_EventSender();
};

class SecondProtocol_Sync {
 public:
  using Proxy_ = ::fidl::test::service::SecondProtocol_SyncProxy;
  virtual ~SecondProtocol_Sync();
  virtual zx_status_t MethodOnSecond() = 0;
};

class SecondProtocol_Proxy final : public ::fidl::internal::Proxy,
                                   public SecondProtocol {
 public:
  explicit SecondProtocol_Proxy(::fidl::internal::ProxyController* controller);
  ~SecondProtocol_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void MethodOnSecond() override;

 private:
  SecondProtocol_Proxy(const ::fidl::test::service::SecondProtocol_Proxy&) =
      delete;
  SecondProtocol_Proxy& operator=(
      const ::fidl::test::service::SecondProtocol_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class SecondProtocol_Stub final
    : public ::fidl::internal::Stub,
      public ::fidl::test::service::SecondProtocol_EventSender {
 public:
  typedef class ::fidl::test::service::SecondProtocol SecondProtocol_clazz;
  explicit SecondProtocol_Stub(
      ::fidl::test::service::SecondProtocol_Stub::SecondProtocol_clazz* impl);
  ~SecondProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::fidl::test::service::SecondProtocol_Stub::SecondProtocol_clazz* impl_;
};

class SecondProtocol_SyncProxy
    : public ::fidl::test::service::SecondProtocol_Sync {
 public:
  explicit SecondProtocol_SyncProxy(::zx::channel channel);
  ~SecondProtocol_SyncProxy() override;
  zx_status_t MethodOnSecond() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<SecondProtocol>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class FirstProtocol {
 public:
  using Proxy_ = ::fidl::test::service::FirstProtocol_Proxy;
  using Stub_ = ::fidl::test::service::FirstProtocol_Stub;
  using EventSender_ = ::fidl::test::service::FirstProtocol_EventSender;
  using Sync_ = ::fidl::test::service::FirstProtocol_Sync;
  virtual ~FirstProtocol();

  virtual void MethodOnFirst() = 0;
};

class FirstProtocol_RequestDecoder {
 public:
  FirstProtocol_RequestDecoder() = default;
  virtual ~FirstProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void MethodOnFirst() = 0;
};

class FirstProtocol_ResponseDecoder {
 public:
  FirstProtocol_ResponseDecoder() = default;
  virtual ~FirstProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

class FirstProtocol_EventSender {
 public:
  virtual ~FirstProtocol_EventSender();
};

class FirstProtocol_Sync {
 public:
  using Proxy_ = ::fidl::test::service::FirstProtocol_SyncProxy;
  virtual ~FirstProtocol_Sync();
  virtual zx_status_t MethodOnFirst() = 0;
};

class FirstProtocol_Proxy final : public ::fidl::internal::Proxy,
                                  public FirstProtocol {
 public:
  explicit FirstProtocol_Proxy(::fidl::internal::ProxyController* controller);
  ~FirstProtocol_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void MethodOnFirst() override;

 private:
  FirstProtocol_Proxy(const ::fidl::test::service::FirstProtocol_Proxy&) =
      delete;
  FirstProtocol_Proxy& operator=(
      const ::fidl::test::service::FirstProtocol_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class FirstProtocol_Stub final
    : public ::fidl::internal::Stub,
      public ::fidl::test::service::FirstProtocol_EventSender {
 public:
  typedef class ::fidl::test::service::FirstProtocol FirstProtocol_clazz;
  explicit FirstProtocol_Stub(
      ::fidl::test::service::FirstProtocol_Stub::FirstProtocol_clazz* impl);
  ~FirstProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::fidl::test::service::FirstProtocol_Stub::FirstProtocol_clazz* impl_;
};

class FirstProtocol_SyncProxy
    : public ::fidl::test::service::FirstProtocol_Sync {
 public:
  explicit FirstProtocol_SyncProxy(::zx::channel channel);
  ~FirstProtocol_SyncProxy() override;
  zx_status_t MethodOnFirst() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<FirstProtocol>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class SingleMemberService final {
 public:
  class Handler;

  static constexpr char Name[] = "fidl.test.service.SingleMemberService";

  explicit SingleMemberService(
      std::unique_ptr<::fidl::ServiceConnector> service)
      : service_(std::move(service)) {}

  explicit operator bool() const { return !!service_; }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "single_member".
  ::fidl::MemberConnector<::fidl::test::service::FirstProtocol> single_member()
      const {
    return ::fidl::MemberConnector<::fidl::test::service::FirstProtocol>(
        service_.get(), "single_member");
  }

 private:
  std::unique_ptr<::fidl::ServiceConnector> service_;
};

/// Facilitates member protocol registration for servers.
class SingleMemberService::Handler final {
 public:
  /// Constructs a new |Handler|. Does not take ownership of |service|.
  explicit Handler(::fidl::ServiceHandlerBase* service) : service_(service) {}
  /// Adds member "single_member" to the service instance. |handler| is invoked
  /// when a connection is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_single_member(
      ::fidl::InterfaceRequestHandler<::fidl::test::service::FirstProtocol>
          handler) {
    return service_->AddMember("single_member", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class MultiHomogeneousMemberService final {
 public:
  class Handler;

  static constexpr char Name[] =
      "fidl.test.service.MultiHomogeneousMemberService";

  explicit MultiHomogeneousMemberService(
      std::unique_ptr<::fidl::ServiceConnector> service)
      : service_(std::move(service)) {}

  explicit operator bool() const { return !!service_; }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "first_member".
  ::fidl::MemberConnector<::fidl::test::service::FirstProtocol> first_member()
      const {
    return ::fidl::MemberConnector<::fidl::test::service::FirstProtocol>(
        service_.get(), "first_member");
  }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "second_member".
  ::fidl::MemberConnector<::fidl::test::service::FirstProtocol> second_member()
      const {
    return ::fidl::MemberConnector<::fidl::test::service::FirstProtocol>(
        service_.get(), "second_member");
  }

 private:
  std::unique_ptr<::fidl::ServiceConnector> service_;
};

/// Facilitates member protocol registration for servers.
class MultiHomogeneousMemberService::Handler final {
 public:
  /// Constructs a new |Handler|. Does not take ownership of |service|.
  explicit Handler(::fidl::ServiceHandlerBase* service) : service_(service) {}
  /// Adds member "first_member" to the service instance. |handler| is invoked
  /// when a connection is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_first_member(
      ::fidl::InterfaceRequestHandler<::fidl::test::service::FirstProtocol>
          handler) {
    return service_->AddMember("first_member", std::move(handler));
  }
  /// Adds member "second_member" to the service instance. |handler| is invoked
  /// when a connection is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_second_member(
      ::fidl::InterfaceRequestHandler<::fidl::test::service::FirstProtocol>
          handler) {
    return service_->AddMember("second_member", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class MultiHeterogeneousMemberService final {
 public:
  class Handler;

  static constexpr char Name[] =
      "fidl.test.service.MultiHeterogeneousMemberService";

  explicit MultiHeterogeneousMemberService(
      std::unique_ptr<::fidl::ServiceConnector> service)
      : service_(std::move(service)) {}

  explicit operator bool() const { return !!service_; }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "first_member".
  ::fidl::MemberConnector<::fidl::test::service::FirstProtocol> first_member()
      const {
    return ::fidl::MemberConnector<::fidl::test::service::FirstProtocol>(
        service_.get(), "first_member");
  }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "second_member".
  ::fidl::MemberConnector<::fidl::test::service::SecondProtocol> second_member()
      const {
    return ::fidl::MemberConnector<::fidl::test::service::SecondProtocol>(
        service_.get(), "second_member");
  }

 private:
  std::unique_ptr<::fidl::ServiceConnector> service_;
};

/// Facilitates member protocol registration for servers.
class MultiHeterogeneousMemberService::Handler final {
 public:
  /// Constructs a new |Handler|. Does not take ownership of |service|.
  explicit Handler(::fidl::ServiceHandlerBase* service) : service_(service) {}
  /// Adds member "first_member" to the service instance. |handler| is invoked
  /// when a connection is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_first_member(
      ::fidl::InterfaceRequestHandler<::fidl::test::service::FirstProtocol>
          handler) {
    return service_->AddMember("first_member", std::move(handler));
  }
  /// Adds member "second_member" to the service instance. |handler| is invoked
  /// when a connection is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_second_member(
      ::fidl::InterfaceRequestHandler<::fidl::test::service::SecondProtocol>
          handler) {
    return service_->AddMember("second_member", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class EmptyService final {
 public:
  class Handler;

  static constexpr char Name[] = "fidl.test.service.EmptyService";

  explicit EmptyService(std::unique_ptr<::fidl::ServiceConnector> service)
      : service_(std::move(service)) {}

  explicit operator bool() const { return !!service_; }

 private:
  std::unique_ptr<::fidl::ServiceConnector> service_;
};

/// Facilitates member protocol registration for servers.
class EmptyService::Handler final {
 public:
  /// Constructs a new |Handler|. Does not take ownership of |service|.
  explicit Handler(::fidl::ServiceHandlerBase* service) { (void)service; }

 private:
};
#endif  // __Fuchsia__

}  // namespace service
}  // namespace test
}  // namespace fidl
