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

#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>

namespace fidl {}  // namespace fidl
template <>
struct ::fidl::internal::NaturalMethodTypes<::test_error::Example::Foo> {
  using Completer = fidl::Completer<
      ::fidl::internal::NaturalCompleterBase<::test_error::Example::Foo>>;

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

  static constexpr bool HasApplicationError = true;

  static constexpr bool IsEmptyStructPayload = false;

  static constexpr bool IsAbsentBody = false;
};
namespace test_error {
__LOCAL extern "C" const fidl_type_t test_error_ExampleFooRequestTable;
__LOCAL extern "C" const fidl_type_t test_error_ExampleFooTopResponseTable;

#ifdef __Fuchsia__
}  // namespace test_error

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

template <>
struct ::fidl::internal::MessageTraits<
    ::fidl::Response<::test_error::Example::Foo>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_error::ExampleFooTopResponse;
};
template <>
class ::fidl::internal::NaturalMessageConverter<
    ::fidl::Response<::test_error::Example::Foo>> {
  using DomainObject = ::test_error::ExampleFooTopResponse;

 public:
  static ::fidl::Response<::test_error::Example::Foo> FromDomainObject(
      DomainObject o) {
    if (o.result().err().has_value()) {
      return ::fitx::error(std::move(o.result().err().value()));
    } else {
      ZX_DEBUG_ASSERT(o.result().response().has_value());
      return ::fitx::ok(std::move(o.result().response().value()));
    }
  }

  static DomainObject IntoDomainObject(
      ::fidl::Response<::test_error::Example::Foo>&& m) {
    if (m.is_error()) {
      return DomainObject{
          {.result = ::test_error::ExampleFooResult::WithErr(m.error_value())}};
    } else {
      return DomainObject{
          {.result = ::test_error::ExampleFooResult::WithResponse(
               std::move(m.value()))}};
    }
  }
};
namespace test_error {}  // namespace test_error
template <>
class ::fidl::Result<::test_error::Example::Foo> final
    : public ::fitx::result<::fidl::AnyErrorIn<::test_error::Example::Foo>,
                            ::test_error::ExampleFooResponse> {
 public:
  using ::fitx::result<::fidl::AnyErrorIn<::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(
      ::fidl::Request<::test_error::Example::Foo> request) const;
};
namespace test_error {
#endif  // __Fuchsia__

}  // namespace test_error
#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_error::Example> {
 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::internal::NaturalEventDispatcher<::test_error::Example> final
    : public ::fidl::internal::IncomingEventDispatcher<
          ::fidl::AsyncEventHandler<::test_error::Example>> {
 public:
  explicit NaturalEventDispatcher(
      ::fidl::AsyncEventHandler<::test_error::Example>* event_handler)
      : IncomingEventDispatcher(event_handler) {}

 private:
  std::optional<::fidl::UnbindInfo> DispatchEvent(
      ::fidl::IncomingMessage& msg,
      internal::IncomingTransportContext transport_context) override;
};
#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__

#ifdef __Fuchsia__

template <>
class ::fidl::Request<::test_error::Example::Foo> final
    : public ::test_error::ExampleFooRequest {
 public:
  using ::test_error::ExampleFooRequest::ExampleFooRequest;
  Request(::test_error::ExampleFooRequest v)
      : ::test_error::ExampleFooRequest(std::move(v)) {}
};

template <>
struct ::fidl::internal::MessageTraits<
    ::fidl::Request<::test_error::Example::Foo>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_error::ExampleFooRequest;
};
#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<::test_error::Example::Foo>
    : public ::fidl::CompleterBase {
 public:
  void Reply(::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 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;

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::NaturalServerDispatcher<::test_error::Example> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_error::Example>* impl,
                       ::fidl::IncomingMessage&& msg,
                       internal::IncomingTransportContext transport_context,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
#endif  // __Fuchsia__
