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

#pragma once

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

namespace fidl {
namespace test {
namespace json {

#ifdef __Fuchsia__

class Parent;
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;
using ParentHandle = ::fidl::InterfaceHandle<Parent>;
namespace internal {
constexpr uint64_t kParent_First_Ordinal = 0x66a95ddc00000000lu;
constexpr uint64_t kParent_First_GenOrdinal = 0x239f8fdea8de880clu;

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

class Child;
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;
using ChildHandle = ::fidl::InterfaceHandle<Child>;
namespace internal {
constexpr uint64_t kChild_First_Ordinal = 0x66a95ddc00000000lu;
constexpr uint64_t kChild_First_GenOrdinal = 0x239f8fdea8de880clu;
constexpr uint64_t kChild_Second_Ordinal = 0x1240cb600000000lu;
constexpr uint64_t kChild_Second_GenOrdinal = 0x24799ea8916d88aflu;

}  // 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();

  virtual void First(::fidl::InterfaceRequest<Parent> request) = 0;
};

class Parent_RequestEncoder {
 public:
  static ::fidl::Message First(::fidl::Encoder* _encoder,
                               ::fidl::InterfaceRequest<Parent>* request) {
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, request, 16);
    return _encoder->GetMessage();
  }
};

class Parent_RequestDecoder {
 public:
  Parent_RequestDecoder() = default;
  virtual ~Parent_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::kParent_First_Ordinal:
      case internal::kParent_First_GenOrdinal: {
        auto arg0 = ::fidl::DecodeAs<::fidl::InterfaceRequest<Parent>>(
            &request_decoder, 16);
        First(std::move(arg0));
        break;
      }
      default: {
        status = ZX_ERR_NOT_SUPPORTED;
        break;
      }
    }
    return status;
  }
  virtual void First(::fidl::InterfaceRequest<Parent> request) = 0;
};

class Parent_ResponseEncoder {
 public:
};

class Parent_ResponseDecoder {
 public:
  Parent_ResponseDecoder() = default;
  virtual ~Parent_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 Parent_EventSender {
 public:
  virtual ~Parent_EventSender();
};

class Parent_Sync {
 public:
  using Proxy_ = Parent_SyncProxy;
  virtual ~Parent_Sync();
  virtual zx_status_t First(::fidl::InterfaceRequest<Parent> request) = 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::Message message) override;
  void First(::fidl::InterfaceRequest<Parent> request) 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::json::Parent Parent_clazz;
  explicit Parent_Stub(Parent_clazz* impl);
  ~Parent_Stub() override;

  zx_status_t Dispatch_(::fidl::Message 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 First(::fidl::InterfaceRequest<Parent> request) 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();

  virtual void First(::fidl::InterfaceRequest<Parent> request) = 0;

  virtual void Second(::fidl::InterfaceRequest<Parent> request) = 0;
};

class Child_RequestEncoder {
 public:
  static ::fidl::Message First(::fidl::Encoder* _encoder,
                               ::fidl::InterfaceRequest<Parent>* request) {
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, request, 16);
    return _encoder->GetMessage();
  }
  static ::fidl::Message Second(::fidl::Encoder* _encoder,
                                ::fidl::InterfaceRequest<Parent>* request) {
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, request, 16);
    return _encoder->GetMessage();
  }
};

class Child_RequestDecoder {
 public:
  Child_RequestDecoder() = default;
  virtual ~Child_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::kChild_First_Ordinal:
      case internal::kChild_First_GenOrdinal: {
        auto arg0 = ::fidl::DecodeAs<::fidl::InterfaceRequest<Parent>>(
            &request_decoder, 16);
        First(std::move(arg0));
        break;
      }
      case internal::kChild_Second_Ordinal:
      case internal::kChild_Second_GenOrdinal: {
        auto arg0 = ::fidl::DecodeAs<::fidl::InterfaceRequest<Parent>>(
            &request_decoder, 16);
        Second(std::move(arg0));
        break;
      }
      default: {
        status = ZX_ERR_NOT_SUPPORTED;
        break;
      }
    }
    return status;
  }
  virtual void First(::fidl::InterfaceRequest<Parent> request) = 0;
  virtual void Second(::fidl::InterfaceRequest<Parent> request) = 0;
};

class Child_ResponseEncoder {
 public:
};

class Child_ResponseDecoder {
 public:
  Child_ResponseDecoder() = default;
  virtual ~Child_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 Child_EventSender {
 public:
  virtual ~Child_EventSender();
};

class Child_Sync {
 public:
  using Proxy_ = Child_SyncProxy;
  virtual ~Child_Sync();
  virtual zx_status_t First(::fidl::InterfaceRequest<Parent> request) = 0;
  virtual zx_status_t Second(::fidl::InterfaceRequest<Parent> request) = 0;
};

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::Message message) override;
  void First(::fidl::InterfaceRequest<Parent> request) override;
  void Second(::fidl::InterfaceRequest<Parent> request) 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::json::Child Child_clazz;
  explicit Child_Stub(Child_clazz* impl);
  ~Child_Stub() override;

  zx_status_t Dispatch_(::fidl::Message 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;
  zx_status_t First(::fidl::InterfaceRequest<Parent> request) override;
  zx_status_t Second(::fidl::InterfaceRequest<Parent> request) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Child>;
};
#endif  // __Fuchsia__
}  // namespace json
}  // namespace test
}  // namespace fidl
namespace fidl {}  // namespace fidl
