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

// fidl_experiment = output_index_json

#pragma once

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

namespace test {
namespace service {

//
// Domain objects declarations
//

#ifdef __Fuchsia__
class EmptyService;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class FirstProtocol;
using FirstProtocolHandle = ::fidl::InterfaceHandle<FirstProtocol>;

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class SingleMemberService;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class SecondProtocol;
using SecondProtocolHandle = ::fidl::InterfaceHandle<SecondProtocol>;

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHeterogeneousMemberService;

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHomogeneousMemberService;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class FirstProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage MethodOnFirst(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};

class FirstProtocol_ResponseEncoder {
 public:
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class SecondProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage MethodOnSecond(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};

class SecondProtocol_ResponseEncoder {
 public:
};

#endif  // __Fuchsia__

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

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace service {

#ifdef __Fuchsia__
class EmptyService;

#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 = 0x5828c91b57492931lu;

constexpr ::fidl::MessageDynamicFlags kFirstProtocol_MethodOnFirst_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class SingleMemberService;

#endif  // __Fuchsia__

#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 = 0x70b439758de25c44lu;

constexpr ::fidl::MessageDynamicFlags kSecondProtocol_MethodOnSecond_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHeterogeneousMemberService;

#endif  // __Fuchsia__

#ifdef __Fuchsia__
class MultiHomogeneousMemberService;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class EmptyService final {
 public:
  class Handler;

  static constexpr char Name[] = "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__

#ifdef __Fuchsia__

class FirstProtocol {
 public:
  using Proxy_ = ::test::service::FirstProtocol_Proxy;
  using Stub_ = ::test::service::FirstProtocol_Stub;
  using EventSender_ = ::test::service::FirstProtocol_EventSender;
  using Sync_ = ::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, bool* is_known);
  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_ = ::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;
  // cts-coverage-fidl-name:test.service/FirstProtocol.MethodOnFirst
  void MethodOnFirst() override;

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

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

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

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

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

class FirstProtocol_SyncProxy : public ::test::service::FirstProtocol_Sync {
 public:
  explicit FirstProtocol_SyncProxy(::zx::channel channel);
  ~FirstProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.service/FirstProtocol.MethodOnFirst
  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[] = "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<::test::service::FirstProtocol> single_member() const {
    return ::fidl::MemberConnector<::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<::test::service::FirstProtocol> handler) {
    return service_->AddMember("single_member", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class SecondProtocol {
 public:
  using Proxy_ = ::test::service::SecondProtocol_Proxy;
  using Stub_ = ::test::service::SecondProtocol_Stub;
  using EventSender_ = ::test::service::SecondProtocol_EventSender;
  using Sync_ = ::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, bool* is_known);
  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_ = ::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;
  // cts-coverage-fidl-name:test.service/SecondProtocol.MethodOnSecond
  void MethodOnSecond() override;

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

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

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

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

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

class SecondProtocol_SyncProxy : public ::test::service::SecondProtocol_Sync {
 public:
  explicit SecondProtocol_SyncProxy(::zx::channel channel);
  ~SecondProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.service/SecondProtocol.MethodOnSecond
  zx_status_t MethodOnSecond() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<SecondProtocol>;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class MultiHeterogeneousMemberService final {
 public:
  class Handler;

  static constexpr char Name[] = "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<::test::service::FirstProtocol> first_member() const {
    return ::fidl::MemberConnector<::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<::test::service::SecondProtocol> second_member() const {
    return ::fidl::MemberConnector<::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<::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<::test::service::SecondProtocol> handler) {
    return service_->AddMember("second_member", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class MultiHomogeneousMemberService final {
 public:
  class Handler;

  static constexpr char Name[] = "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<::test::service::FirstProtocol> first_member() const {
    return ::fidl::MemberConnector<::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<::test::service::FirstProtocol> second_member() const {
    return ::fidl::MemberConnector<::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<::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<::test::service::FirstProtocol> handler) {
    return service_->AddMember("second_member", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};

#endif  // __Fuchsia__

}  // namespace service
}  // namespace test
