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

#pragma once

#include <fidl/test.errorsyntax.parent/cpp/natural_messaging.h>
#include <fidl/test.errorsyntax/cpp/markers.h>
#include <fidl/test.errorsyntax/cpp/natural_types.h>
#include <fidl/test.errorsyntax/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_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail> {
  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>>;

  using ResultCallback = ::fit::callback<void(
      ::fidl::Result<::test_errorsyntax::ExampleUseOfErrorSyntax::
                         ComposedCallWhichMayFail>&)>;

  static constexpr bool HasApplicationError = true;

  static constexpr bool IsEmptyStructPayload = false;

  static constexpr bool IsAbsentBody = false;
};

template <>
struct ::fidl::internal::NaturalMethodTypes<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail> {
  using Completer = fidl::Completer<::fidl::internal::NaturalCompleterBase<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>>;

  using ResultCallback = ::fit::callback<void(
      ::fidl::Result<
          ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>&)>;

  static constexpr bool HasApplicationError = true;

  static constexpr bool IsEmptyStructPayload = false;

  static constexpr bool IsAbsentBody = false;
};
namespace test_errorsyntax {
__LOCAL extern "C" const fidl_type_t
    test_errorsyntax_parent_ParentUsesErrorSyntaxComposedCallWhichMayFailRequestTable;
__LOCAL extern "C" const fidl_type_t
    test_errorsyntax_parent_ParentUsesErrorSyntaxComposedCallWhichMayFailTopResponseTable;
__LOCAL extern "C" const fidl_type_t
    test_errorsyntax_ExampleUseOfErrorSyntaxCallWhichMayFailRequestTable;
__LOCAL extern "C" const fidl_type_t
    test_errorsyntax_ExampleUseOfErrorSyntaxCallWhichMayFailTopResponseTable;

#ifdef __Fuchsia__
}  // namespace test_errorsyntax

template <>
class ::fidl::Response<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
    final
    : public ::fitx::result<
          uint32_t, ::test_errorsyntax_parent::
                        ParentUsesErrorSyntaxComposedCallWhichMayFailResponse> {
 public:
  using ::fitx::result<
      uint32_t,
      ::test_errorsyntax_parent::
          ParentUsesErrorSyntaxComposedCallWhichMayFailResponse>::result;
  Response(::fitx::result<
           uint32_t, ::test_errorsyntax_parent::
                         ParentUsesErrorSyntaxComposedCallWhichMayFailResponse>
               v)
      : result(std::move(v)) {}
  Response() = delete;
};

template <>
struct ::fidl::internal::MessageTraits<::fidl::Response<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_errorsyntax_parent::
      ParentUsesErrorSyntaxComposedCallWhichMayFailTopResponse;
};
template <>
class ::fidl::internal::NaturalMessageConverter<::fidl::Response<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>> {
  using DomainObject = ::test_errorsyntax_parent::
      ParentUsesErrorSyntaxComposedCallWhichMayFailTopResponse;

 public:
  static ::fidl::Response<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
  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_errorsyntax::ExampleUseOfErrorSyntax::
                           ComposedCallWhichMayFail>&& m) {
    if (m.is_error()) {
      return DomainObject{
          {.result = ::test_errorsyntax_parent::
               ParentUsesErrorSyntaxComposedCallWhichMayFailResult::WithErr(
                   m.error_value())}};
    } else {
      return DomainObject{
          {.result = ::test_errorsyntax_parent::
               ParentUsesErrorSyntaxComposedCallWhichMayFailResult::
                   WithResponse(std::move(m.value()))}};
    }
  }
};
namespace test_errorsyntax {}  // namespace test_errorsyntax
template <>
class ::fidl::Result<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
    final : public ::fitx::result<
                ::fidl::AnyErrorIn<::test_errorsyntax::ExampleUseOfErrorSyntax::
                                       ComposedCallWhichMayFail>,
                ::test_errorsyntax_parent::
                    ParentUsesErrorSyntaxComposedCallWhichMayFailResponse> {
 public:
  using ::fitx::result<
      ::fidl::AnyErrorIn<::test_errorsyntax::ExampleUseOfErrorSyntax::
                             ComposedCallWhichMayFail>,
      ::test_errorsyntax_parent::
          ParentUsesErrorSyntaxComposedCallWhichMayFailResponse>::result;

 protected:
  Result() = default;
};

template <>
class ::fidl::Response<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
    final
    : public ::fitx::result<
          uint32_t,
          ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailResponse> {
 public:
  using ::fitx::result<
      uint32_t, ::test_errorsyntax::
                    ExampleUseOfErrorSyntaxCallWhichMayFailResponse>::result;
  Response(::fitx::result<
           uint32_t,
           ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailResponse>
               v)
      : result(std::move(v)) {}
  Response() = delete;
};

template <>
struct ::fidl::internal::MessageTraits<::fidl::Response<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload =
      ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailTopResponse;
};
template <>
class ::fidl::internal::NaturalMessageConverter<::fidl::Response<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>> {
  using DomainObject =
      ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailTopResponse;

 public:
  static ::fidl::Response<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
  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_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>&& m) {
    if (m.is_error()) {
      return DomainObject{
          {.result = ::test_errorsyntax::
               ExampleUseOfErrorSyntaxCallWhichMayFailResult::WithErr(
                   m.error_value())}};
    } else {
      return DomainObject{
          {.result = ::test_errorsyntax::
               ExampleUseOfErrorSyntaxCallWhichMayFailResult::WithResponse(
                   std::move(m.value()))}};
    }
  }
};
template <>
class ::fidl::Result<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
    final
    : public ::fitx::result<
          ::fidl::AnyErrorIn<
              ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>,
          ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailResponse> {
 public:
  using ::fitx::result<
      ::fidl::AnyErrorIn<
          ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>,
      ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailResponse>::
      result;

 protected:
  Result() = default;
};

template <>
class ::fidl::internal::NaturalClientImpl<
    ::test_errorsyntax::ExampleUseOfErrorSyntax>
    final : public ::fidl::internal::NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;
  ::fidl::internal::NaturalThenable<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
  ComposedCallWhichMayFail(
      ::fidl::Request<
          ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
          request) const;

  ::fidl::internal::NaturalThenable<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
  CallWhichMayFail(
      ::fidl::Request<
          ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
          request) const;
};
namespace test_errorsyntax {
#endif  // __Fuchsia__

}  // namespace test_errorsyntax
#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<
    ::test_errorsyntax::ExampleUseOfErrorSyntax> {
 public:
  NaturalEventHandlerInterface() = default;
  virtual ~NaturalEventHandlerInterface() = default;
};

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

template <>
class ::fidl::internal::NaturalEventDispatcher<
    ::test_errorsyntax::ExampleUseOfErrorSyntax>
    final : public ::fidl::internal::IncomingEventDispatcher<
                ::fidl::AsyncEventHandler<
                    ::test_errorsyntax::ExampleUseOfErrorSyntax>> {
 public:
  explicit NaturalEventDispatcher(
      ::fidl::AsyncEventHandler<::test_errorsyntax::ExampleUseOfErrorSyntax>*
          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_errorsyntax::ExampleUseOfErrorSyntax>
    : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::NaturalEventSender<
    ::test_errorsyntax::ExampleUseOfErrorSyntax>
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::NaturalEventSender<
              ::test_errorsyntax::ExampleUseOfErrorSyntax>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::Request<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
    final : public ::test_errorsyntax_parent::
                ParentUsesErrorSyntaxComposedCallWhichMayFailRequest {
 public:
  using ::test_errorsyntax_parent::
      ParentUsesErrorSyntaxComposedCallWhichMayFailRequest::
          ParentUsesErrorSyntaxComposedCallWhichMayFailRequest;
  Request(::test_errorsyntax_parent::
              ParentUsesErrorSyntaxComposedCallWhichMayFailRequest v)
      : ::test_errorsyntax_parent::
            ParentUsesErrorSyntaxComposedCallWhichMayFailRequest(std::move(v)) {
  }
};

template <>
struct ::fidl::internal::MessageTraits<::fidl::Request<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload = ::test_errorsyntax_parent::
      ParentUsesErrorSyntaxComposedCallWhichMayFailRequest;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::Request<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
    final : public ::test_errorsyntax::
                ExampleUseOfErrorSyntaxCallWhichMayFailRequest {
 public:
  using ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest::
      ExampleUseOfErrorSyntaxCallWhichMayFailRequest;
  Request(::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest v)
      : ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest(
            std::move(v)) {}
};

template <>
struct ::fidl::internal::MessageTraits<::fidl::Request<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>>
    final {
 public:
  static constexpr bool kHasPayload = true;
  using Payload =
      ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest;
};
#endif  // __Fuchsia__

template <>
class ::fidl::internal::NaturalCompleterBase<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>
    : public ::fidl::CompleterBase {
 public:
  void Reply(::fidl::Response<::test_errorsyntax::ExampleUseOfErrorSyntax::
                                  ComposedCallWhichMayFail>&& response);

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

template <>
class ::fidl::internal::NaturalCompleterBase<
    ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>
    : public ::fidl::CompleterBase {
 public:
  void Reply(::fidl::Response<
             ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>&&
                 response);

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

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

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

  using ComposedCallWhichMayFailRequest = ::fidl::Request<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>;
  using ComposedCallWhichMayFailCompleter = ::fidl::internal::NaturalCompleter<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>;

  virtual void ComposedCallWhichMayFail(
      ComposedCallWhichMayFailRequest& request,
      ComposedCallWhichMayFailCompleter::Sync& completer) = 0;

  using CallWhichMayFailRequest = ::fidl::Request<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>;
  using CallWhichMayFailCompleter = ::fidl::internal::NaturalCompleter<
      ::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>;

  virtual void CallWhichMayFail(CallWhichMayFailRequest& request,
                                CallWhichMayFailCompleter::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_errorsyntax::ExampleUseOfErrorSyntax>
    final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(
      ::fidl::Server<::test_errorsyntax::ExampleUseOfErrorSyntax>* 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__
