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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.protocolrequest/cpp/markers.h>
#include <fidl/test.protocolrequest/cpp/natural_types.h>
#include <fidl/test.protocolrequest/cpp/wire_messaging.h>
#include <lib/fidl/cpp/channel.h>
#include <lib/fidl/cpp/client.h>
#include <lib/fidl/cpp/internal/thenable.h>
#include <lib/fidl/cpp/natural_types.h>
#include <lib/fidl/cpp/unified_messaging.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class ::fidl::internal::NaturalClientImpl<::test_protocolrequest::Child> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
};
namespace fidl {

#endif  // __Fuchsia__

}  // namespace fidl

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_protocolrequest::Child> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_protocolrequest::Child>> {
 public:
 private:
  ::fidl::UnownedClientEnd<::test_protocolrequest::Child> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_protocolrequest::Child>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Child> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  NaturalEventHandlerInterface() = default;
  virtual ~NaturalEventHandlerInterface() = default;
};

template <>
class ::fidl::AsyncEventHandler<::test_protocolrequest::Child>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Child>, public ::fidl::internal::AsyncEventHandler {
 public:
  AsyncEventHandler() = default;
};

template <>
class ::fidl::SyncEventHandler<::test_protocolrequest::Child>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Child>, public ::fidl::internal::SyncEventHandler {
 public:
  SyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the corresponding virtual
  // method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Child> client_end);
};

template <>
class ::fidl::internal::NaturalEventDispatcher<::test_protocolrequest::Child> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Child>> {
 public:
  explicit NaturalEventDispatcher(::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Child>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
class ::fidl::internal::NaturalWeakEventSender<::test_protocolrequest::Child> : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::NaturalEventSender<::test_protocolrequest::Child>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalEventSender<::test_protocolrequest::Child>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

#endif  // __Fuchsia__

template <>
class ::fidl::Server<::test_protocolrequest::Child> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  Server() = default;
  virtual ~Server() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_protocolrequest::Child;

  using Handler = fidl::ProtocolHandler<::test_protocolrequest::Child>;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_protocolrequest::Child> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<::test_protocolrequest::Child> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_protocolrequest::Child>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_protocolrequest::Parent::GetChild> {
  using Response = ::test_protocolrequest::ParentGetChildResponse;

  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<::test_protocolrequest::Parent::GetChild>>;
  using ResultCallback =
      ::fit::callback<void(::fidl::Result<::test_protocolrequest::Parent::GetChild>&)>;
};

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_protocolrequest::Parent::GetChildRequest> {
  using Response = ::test_protocolrequest::ParentGetChildRequestResponse;

  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<::test_protocolrequest::Parent::GetChildRequest>>;
  using ResultCallback =
      ::fit::callback<void(::fidl::Result<::test_protocolrequest::Parent::GetChildRequest>&)>;
};

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_protocolrequest::Parent::TakeChild> {
  using Request = ::test_protocolrequest::ParentTakeChildRequest;

  using Completer = fidl::Completer<>;
};

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_protocolrequest::Parent::TakeChildRequest> {
  using Request = ::test_protocolrequest::ParentTakeChildRequestRequest;

  using Completer = fidl::Completer<>;
};

#ifdef __Fuchsia__

template <>
class ::fidl::Response<::test_protocolrequest::Parent::GetChild> final : public ::test_protocolrequest::ParentGetChildResponse {
 public:
  using ::test_protocolrequest::ParentGetChildResponse::ParentGetChildResponse;
  Response(::test_protocolrequest::ParentGetChildResponse v) : ParentGetChildResponse(std::move(v)) {}
};

template <>
class ::fidl::Result<::test_protocolrequest::Parent::GetChild> final : public ::fit::result<::fidl::Error, ::test_protocolrequest::ParentGetChildResponse> {
 public:
  using ::fit::result<::fidl::Error, ::test_protocolrequest::ParentGetChildResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::Response<::test_protocolrequest::Parent::GetChildRequest> final : public ::test_protocolrequest::ParentGetChildRequestResponse {
 public:
  using ::test_protocolrequest::ParentGetChildRequestResponse::ParentGetChildRequestResponse;
  Response(::test_protocolrequest::ParentGetChildRequestResponse v) : ParentGetChildRequestResponse(std::move(v)) {}
};

template <>
class ::fidl::Result<::test_protocolrequest::Parent::GetChildRequest> final : public ::fit::result<::fidl::Error, ::test_protocolrequest::ParentGetChildRequestResponse> {
 public:
  using ::fit::result<::fidl::Error, ::test_protocolrequest::ParentGetChildRequestResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::internal::NaturalClientImpl<::test_protocolrequest::Parent> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fidl::internal::NaturalThenable<::test_protocolrequest::Parent::GetChild> GetChild() const;

  ::fidl::internal::NaturalThenable<::test_protocolrequest::Parent::GetChildRequest> GetChildRequest() const;

  ::fit::result<::fidl::OneWayError> TakeChild(::fidl::Request<::test_protocolrequest::Parent::TakeChild> request) const;

  ::fit::result<::fidl::OneWayError> TakeChildRequest(::fidl::Request<::test_protocolrequest::Parent::TakeChildRequest> request) const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_protocolrequest::Parent> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_protocolrequest::Parent>> {
 public:
  ::fidl::Result<::test_protocolrequest::Parent::GetChild> GetChild();

  ::fidl::Result<::test_protocolrequest::Parent::GetChildRequest> GetChildRequest();

  ::fit::result<::fidl::OneWayError> TakeChild(::fidl::Request<::test_protocolrequest::Parent::TakeChild> request);

  ::fit::result<::fidl::OneWayError> TakeChildRequest(::fidl::Request<::test_protocolrequest::Parent::TakeChildRequest> request);

 private:
  ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_protocolrequest::Parent>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Parent> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  NaturalEventHandlerInterface() = default;
  virtual ~NaturalEventHandlerInterface() = default;
};

template <>
class ::fidl::AsyncEventHandler<::test_protocolrequest::Parent>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Parent>, public ::fidl::internal::AsyncEventHandler {
 public:
  AsyncEventHandler() = default;
};

template <>
class ::fidl::SyncEventHandler<::test_protocolrequest::Parent>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Parent>, public ::fidl::internal::SyncEventHandler {
 public:
  SyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the corresponding virtual
  // method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end);
};

template <>
class ::fidl::internal::NaturalEventDispatcher<::test_protocolrequest::Parent> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Parent>> {
 public:
  explicit NaturalEventDispatcher(::fidl::internal::NaturalEventHandlerInterface<::test_protocolrequest::Parent>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
class ::fidl::internal::NaturalWeakEventSender<::test_protocolrequest::Parent> : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::NaturalEventSender<::test_protocolrequest::Parent>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalEventSender<::test_protocolrequest::Parent>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<::test_protocolrequest::Parent::GetChild> : public ::fidl::CompleterBase {
 public:
  void Reply(::fidl::Response<::test_protocolrequest::Parent::GetChild> response);

 protected:
  using ::fidl::CompleterBase::CompleterBase;
};

template <>
class ::fidl::internal::NaturalCompleterBase<::test_protocolrequest::Parent::GetChildRequest> : public ::fidl::CompleterBase {
 public:
  void Reply(::fidl::Response<::test_protocolrequest::Parent::GetChildRequest> response);

 protected:
  using ::fidl::CompleterBase::CompleterBase;
};

template <>
class ::fidl::Server<::test_protocolrequest::Parent> : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  Server() = default;
  virtual ~Server() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_protocolrequest::Parent;

  using Handler = fidl::ProtocolHandler<::test_protocolrequest::Parent>;

  using GetChildCompleter = ::fidl::internal::NaturalCompleter<::test_protocolrequest::Parent::GetChild>;

  virtual void GetChild(
      GetChildCompleter::Sync& completer) = 0;

  using GetChildRequestCompleter = ::fidl::internal::NaturalCompleter<::test_protocolrequest::Parent::GetChildRequest>;

  virtual void GetChildRequest(
      GetChildRequestCompleter::Sync& completer) = 0;

  using TakeChildRequest = ::fidl::Request<::test_protocolrequest::Parent::TakeChild>;
  using TakeChildCompleter = ::fidl::internal::NaturalCompleter<::test_protocolrequest::Parent::TakeChild>;

  virtual void TakeChild(TakeChildRequest& request,
                         TakeChildCompleter::Sync& completer) = 0;

  using TakeChildRequestRequest = ::fidl::Request<::test_protocolrequest::Parent::TakeChildRequest>;
  using TakeChildRequestCompleter = ::fidl::internal::NaturalCompleter<::test_protocolrequest::Parent::TakeChildRequest>;

  virtual void TakeChildRequest(TakeChildRequestRequest& request,
                                TakeChildRequestCompleter::Sync& completer) = 0;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_protocolrequest::Parent> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<::test_protocolrequest::Parent> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_protocolrequest::Parent>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop
