// 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 protocolrequest {

#ifdef __Fuchsia__
class Parent;
using ParentHandle = ::fidl::InterfaceHandle<Parent>;
#endif  // __Fuchsia__
#ifdef __Fuchsia__
class Child;
using ChildHandle = ::fidl::InterfaceHandle<Child>;
#endif  // __Fuchsia__
#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildRequestRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentTakeChildRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentTakeChildRequestRequestTable;
}  // namespace _internal

class Parent_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage GetChild(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(DidHLCPPEncode,
               &_internal::fidl_test_protocolrequest_ParentGetChildRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage GetChildRequest(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocolrequest_ParentGetChildRequestRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TakeChild(
      ::fidl::Encoder* _encoder,
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>* c) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, c, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocolrequest_ParentTakeChildRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TakeChildRequest(
      ::fidl::Encoder* _encoder,
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child>* r) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, r, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::
                   fidl_test_protocolrequest_ParentTakeChildRequestRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocolrequest_ParentGetChildRequestResponseTable;
}  // namespace _internal

class Parent_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage GetChild(
      ::fidl::Encoder* _encoder,
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>* c) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, c, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocolrequest_ParentGetChildResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage GetChildRequest(
      ::fidl::Encoder* _encoder,
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child>* r) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, r, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::
                   fidl_test_protocolrequest_ParentGetChildRequestResponseTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__
#ifdef __Fuchsia__

namespace _internal {}

class Child_RequestEncoder {
 public:
};

namespace _internal {}

class Child_ResponseEncoder {
 public:
};

#endif  // __Fuchsia__
}  // namespace protocolrequest
}  // namespace test
}  // namespace fidl
namespace fidl {}  // namespace fidl

//
// Proxies and stubs declarations
//
namespace fidl {
namespace test {
namespace protocolrequest {

#ifdef __Fuchsia__
using ParentPtr = ::fidl::InterfacePtr<Parent>;
class Parent_Proxy;
class Parent_Stub;
class Parent_EventSender;
class Parent_Sync;
using ParentSyncPtr = ::fidl::SynchronousInterfacePtr<Parent>;
class Parent_SyncProxy;

namespace internal {
constexpr uint64_t kParent_GetChild_Ordinal = 0x6e0c789be8dbb77elu;
constexpr uint64_t kParent_GetChildRequest_Ordinal = 0x193e7d6949a9df98lu;
constexpr uint64_t kParent_TakeChild_Ordinal = 0x5311bd7214c0f6elu;
constexpr uint64_t kParent_TakeChildRequest_Ordinal = 0x15dae312bad5a9cclu;

}  // namespace internal
#endif  // __Fuchsia__
#ifdef __Fuchsia__
using ChildPtr = ::fidl::InterfacePtr<Child>;
class Child_Proxy;
class Child_Stub;
class Child_EventSender;
class Child_Sync;
using ChildSyncPtr = ::fidl::SynchronousInterfacePtr<Child>;
class Child_SyncProxy;

namespace internal {}  // namespace internal
#endif                 // __Fuchsia__
#ifdef __Fuchsia__
class Parent {
 public:
  using Proxy_ = Parent_Proxy;
  using Stub_ = Parent_Stub;
  using EventSender_ = Parent_EventSender;
  using Sync_ = Parent_Sync;
  virtual ~Parent();
  using GetChildCallback = fit::function<void(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>)>;

  virtual void GetChild(GetChildCallback callback) = 0;
  using GetChildRequestCallback = fit::function<void(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child>)>;

  virtual void GetChildRequest(GetChildRequestCallback callback) = 0;

  virtual void TakeChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>
          c) = 0;

  virtual void TakeChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r) = 0;
};

class Parent_RequestDecoder {
 public:
  Parent_RequestDecoder() = default;
  virtual ~Parent_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void GetChild() = 0;
  virtual void GetChildRequest() = 0;
  virtual void TakeChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>
          c) = 0;
  virtual void TakeChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r) = 0;
};

class Parent_ResponseDecoder {
 public:
  Parent_ResponseDecoder() = default;
  virtual ~Parent_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void GetChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>
          c) = 0;
  virtual void GetChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r) = 0;
};

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

class Parent_Sync {
 public:
  using Proxy_ = Parent_SyncProxy;
  virtual ~Parent_Sync();
  virtual zx_status_t GetChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>*
          out_c) = 0;
  virtual zx_status_t GetChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child>*
          out_r) = 0;
  virtual zx_status_t TakeChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>
          c) = 0;
  virtual zx_status_t TakeChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void GetChild(GetChildCallback callback) override;
  void GetChildRequest(GetChildRequestCallback callback) override;
  void TakeChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child> c)
      override;
  void TakeChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r)
      override;

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

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

class Parent_Stub final : public ::fidl::internal::Stub,
                          public Parent_EventSender {
 public:
  typedef class ::fidl::test::protocolrequest::Parent Parent_clazz;
  explicit Parent_Stub(Parent_clazz* impl);
  ~Parent_Stub() override;

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

 private:
  Parent_clazz* impl_;
};

class Parent_SyncProxy : public Parent_Sync {
 public:
  explicit Parent_SyncProxy(::zx::channel channel);
  ~Parent_SyncProxy() override;
  zx_status_t GetChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child>*
          out_c) override;
  zx_status_t GetChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child>* out_r)
      override;
  zx_status_t TakeChild(
      ::fidl::InterfaceHandle<class ::fidl::test::protocolrequest::Child> c)
      override;
  zx_status_t TakeChildRequest(
      ::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r)
      override;

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

#endif  // __Fuchsia__
#ifdef __Fuchsia__
class Child {
 public:
  using Proxy_ = Child_Proxy;
  using Stub_ = Child_Stub;
  using EventSender_ = Child_EventSender;
  using Sync_ = Child_Sync;
  virtual ~Child();
};

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

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

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

class Child_Sync {
 public:
  using Proxy_ = Child_SyncProxy;
  virtual ~Child_Sync();
};

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

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

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

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

class Child_Stub final : public ::fidl::internal::Stub,
                         public Child_EventSender {
 public:
  typedef class ::fidl::test::protocolrequest::Child Child_clazz;
  explicit Child_Stub(Child_clazz* impl);
  ~Child_Stub() override;

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

 private:
  Child_clazz* impl_;
};

class Child_SyncProxy : public Child_Sync {
 public:
  explicit Child_SyncProxy(::zx::channel channel);
  ~Child_SyncProxy() override;

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

#endif  // __Fuchsia__
}  // namespace protocolrequest
}  // namespace test
}  // namespace fidl
