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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.error/cpp/markers.h>
#include <fidl/test.error/cpp/natural_types.h>
#include <fidl/test.error/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 {

}  // namespace fidl

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_error::Example::Foo> {
  using Request = ::test_error::ExampleFooRequest;

  using Response = ::test_error::ExampleFooResult;

  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<::test_error::Example::Foo>>;
  using ResultCallback =
      ::fit::callback<void(::fidl::Result<::test_error::Example::Foo>&)>;
};

#ifdef __Fuchsia__

template <>
class ::fidl::Response<::test_error::Example::Foo> final : public ::fit::result<uint32_t, ::test_error::ExampleFooResponse> {
 public:
  using ::fit::result<uint32_t, ::test_error::ExampleFooResponse>::result;
  Response(::fit::result<uint32_t, ::test_error::ExampleFooResponse> v) : result(std::move(v)) {}
  Response() = delete;
};
template <>
class ::fidl::internal::ResponseMessageConverter<::test_error::Example::Foo> {
  using DomainObject = ::test_error::ExampleFooResult;

 public:
  static DomainObject IntoDomainObject(const ::fidl::Response<::test_error::Example::Foo>& m) {
    if (m.is_error()) {
      return DomainObject::WithErr(m.error_value());
    } else {
      return DomainObject::WithResponse(std::move(m.value()));
    }
  }
};

template <>
class ::fidl::Result<::test_error::Example::Foo> final : public ::fit::result<::fidl::ErrorsIn<::test_error::Example::Foo>, ::test_error::ExampleFooResponse> {
 public:
  using ::fit::result<::fidl::ErrorsIn<::test_error::Example::Foo>, ::test_error::ExampleFooResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::internal::NaturalClientImpl<::test_error::Example> final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fidl::internal::NaturalThenable<::test_error::Example::Foo> Foo(const ::fidl::Request<::test_error::Example::Foo>& request) const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_error::Example> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_error::Example>> {
 public:
  ::fidl::Result<::test_error::Example::Foo> Foo(const ::fidl::Request<::test_error::Example::Foo>& request);

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

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

template <>
class ::fidl::SyncEventHandler<::test_error::Example>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_error::Example>, 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_error::Example> client_end);
};

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

#endif  // __Fuchsia__

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

template <>
class ::fidl::internal::NaturalEventSender<::test_error::Example>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalEventSender<::test_error::Example>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<::test_error::Example::Foo> : public ::fidl::CompleterBase {
 public:
  void Reply(const ::fidl::Response<::test_error::Example::Foo>& response);

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

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

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

  using Handler = fidl::ProtocolHandler<::test_error::Example>;

  using FooRequest = ::fidl::Request<::test_error::Example::Foo>;
  using FooCompleter = ::fidl::internal::NaturalCompleter<::test_error::Example::Foo>;

  virtual void Foo(FooRequest& request,
                   FooCompleter::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_error::Example> 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_error::Example> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_error::Example>* 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
