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

#pragma once

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

namespace fidl {
namespace test {
namespace service {

#ifdef __Fuchsia__

class SecondProtocol;
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;
using SecondProtocolHandle = ::fidl::InterfaceHandle<SecondProtocol>;
namespace internal {
constexpr uint64_t kSecondProtocol_MethodOnSecond_Ordinal =
    0x54ea6448c1555a29lu;

}  // namespace internal
#endif  // __Fuchsia__
#ifdef __Fuchsia__

class FirstProtocol;
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;
using FirstProtocolHandle = ::fidl::InterfaceHandle<FirstProtocol>;
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_ = SecondProtocol_Proxy;
  using Stub_ = SecondProtocol_Stub;
  using EventSender_ = SecondProtocol_EventSender;
  using Sync_ = 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);
  zx_status_t Decode_(::fidl::Message request) {
    bool needs_response;
    const fidl_type_t* request_type =
        GetType(request.ordinal(), &needs_response);
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = request.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(request, request_type, error_msg);
      return status;
    }
    ::fidl::Decoder request_decoder(std::move(request));
    switch (request.ordinal()) {
      case internal::kSecondProtocol_MethodOnSecond_Ordinal: {
        MethodOnSecond();
        break;
      }
      default: {
        status = ZX_ERR_NOT_SUPPORTED;
        break;
      }
    }
    return status;
  }
  virtual void MethodOnSecond() = 0;
};

class SecondProtocol_RequestEncoder {
 public:
  static ::fidl::Message MethodOnSecond(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    bool needs_response;  // unused
    fidl_trace(
        DidHLCPPEncode,
        SecondProtocol_RequestDecoder::GetType(
            internal::kSecondProtocol_MethodOnSecond_Ordinal, &needs_response),
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

class SecondProtocol_ResponseDecoder {
 public:
  SecondProtocol_ResponseDecoder() = default;
  virtual ~SecondProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  zx_status_t Decode_(::fidl::Message response) {
    const fidl_type_t* response_type = GetType(response.ordinal());
    if (response_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = response.Decode(response_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(response, response_type, error_msg);
      return status;
    }
    ::fidl::Decoder response_decoder(std::move(response));
    switch (response.ordinal()) {
      default: {
        break;
      }
    }
    return ZX_OK;
  }
};

class SecondProtocol_ResponseEncoder {
 public:
};

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

class SecondProtocol_Sync {
 public:
  using Proxy_ = 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::Message message) override;
  void MethodOnSecond() override;

 private:
  SecondProtocol_Proxy(const SecondProtocol_Proxy&) = delete;
  SecondProtocol_Proxy& operator=(const SecondProtocol_Proxy&) = delete;

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

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

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

 private:
  SecondProtocol_clazz* impl_;
};

class SecondProtocol_SyncProxy : public 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_ = FirstProtocol_Proxy;
  using Stub_ = FirstProtocol_Stub;
  using EventSender_ = FirstProtocol_EventSender;
  using Sync_ = 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);
  zx_status_t Decode_(::fidl::Message request) {
    bool needs_response;
    const fidl_type_t* request_type =
        GetType(request.ordinal(), &needs_response);
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = request.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(request, request_type, error_msg);
      return status;
    }
    ::fidl::Decoder request_decoder(std::move(request));
    switch (request.ordinal()) {
      case internal::kFirstProtocol_MethodOnFirst_Ordinal: {
        MethodOnFirst();
        break;
      }
      default: {
        status = ZX_ERR_NOT_SUPPORTED;
        break;
      }
    }
    return status;
  }
  virtual void MethodOnFirst() = 0;
};

class FirstProtocol_RequestEncoder {
 public:
  static ::fidl::Message MethodOnFirst(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    bool needs_response;  // unused
    fidl_trace(
        DidHLCPPEncode,
        FirstProtocol_RequestDecoder::GetType(
            internal::kFirstProtocol_MethodOnFirst_Ordinal, &needs_response),
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

class FirstProtocol_ResponseDecoder {
 public:
  FirstProtocol_ResponseDecoder() = default;
  virtual ~FirstProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  zx_status_t Decode_(::fidl::Message response) {
    const fidl_type_t* response_type = GetType(response.ordinal());
    if (response_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = response.Decode(response_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(response, response_type, error_msg);
      return status;
    }
    ::fidl::Decoder response_decoder(std::move(response));
    switch (response.ordinal()) {
      default: {
        break;
      }
    }
    return ZX_OK;
  }
};

class FirstProtocol_ResponseEncoder {
 public:
};

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

class FirstProtocol_Sync {
 public:
  using Proxy_ = 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::Message message) override;
  void MethodOnFirst() override;

 private:
  FirstProtocol_Proxy(const FirstProtocol_Proxy&) = delete;
  FirstProtocol_Proxy& operator=(const FirstProtocol_Proxy&) = delete;

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

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

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

 private:
  FirstProtocol_clazz* impl_;
};

class FirstProtocol_SyncProxy : public 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<FirstProtocol> single_member() const {
    return ::fidl::MemberConnector<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<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<FirstProtocol> first_member() const {
    return ::fidl::MemberConnector<FirstProtocol>(service_.get(),
                                                  "first_member");
  }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "second_member".
  ::fidl::MemberConnector<FirstProtocol> second_member() const {
    return ::fidl::MemberConnector<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<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<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<FirstProtocol> first_member() const {
    return ::fidl::MemberConnector<FirstProtocol>(service_.get(),
                                                  "first_member");
  }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the
  /// member protocol "second_member".
  ::fidl::MemberConnector<SecondProtocol> second_member() const {
    return ::fidl::MemberConnector<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<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<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
namespace fidl {}  // namespace fidl
