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

// fidl_experiment = output_index_json

#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>
#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_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail> {
  using Request = ::test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailRequest;

  using Response = ::test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResult;

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

template <>
struct ::fidl::internal::NaturalMethodTypes<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail> {
  using Request = ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest;

  using Response = ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailResult;

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

#ifdef __Fuchsia__

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

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

template <>
class ::fidl::Result<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail> final : public ::fit::result<::fidl::ErrorsIn<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>, ::test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResponse> {
 public:
  using ::fit::result<::fidl::ErrorsIn<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>, ::test_errorsyntax_parent::ParentUsesErrorSyntaxComposedCallWhichMayFailResponse>::result;

 protected:
  Result() = default;
};

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

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

template <>
class ::fidl::Result<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail> final : public ::fit::result<::fidl::ErrorsIn<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>, ::test_errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailResponse> {
 public:
  using ::fit::result<::fidl::ErrorsIn<::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(const ::fidl::Request<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>& request) const;

  ::fidl::internal::NaturalThenable<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail> CallWhichMayFail(const ::fidl::Request<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>& request) const;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalSyncClientImpl<::test_errorsyntax::ExampleUseOfErrorSyntax> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::NaturalSyncClientImpl<::test_errorsyntax::ExampleUseOfErrorSyntax>> {
 public:
  ::fidl::Result<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail> ComposedCallWhichMayFail(const ::fidl::Request<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail>& request);

  ::fidl::Result<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail> CallWhichMayFail(const ::fidl::Request<::test_errorsyntax::ExampleUseOfErrorSyntax::CallWhichMayFail>& request);

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::NaturalEventHandlerInterface<::test_errorsyntax::ExampleUseOfErrorSyntax> : public ::fidl::internal::BaseEventHandlerInterface {
 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::SyncEventHandler<::test_errorsyntax::ExampleUseOfErrorSyntax>
    : public ::fidl::internal::NaturalEventHandlerInterface<::test_errorsyntax::ExampleUseOfErrorSyntax>, 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_errorsyntax::ExampleUseOfErrorSyntax> client_end);
};

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

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

template <>
class ::fidl::internal::NaturalCompleterBase<::test_errorsyntax::ExampleUseOfErrorSyntax::ComposedCallWhichMayFail> : public ::fidl::CompleterBase {
 public:
  void Reply(const ::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(const ::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 Handler = fidl::ProtocolHandler<::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;

  // |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_errorsyntax::ExampleUseOfErrorSyntax> 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_errorsyntax::ExampleUseOfErrorSyntax> final {
  NaturalServerDispatcher() = delete;
  static void Dispatch(::fidl::Server<::test_errorsyntax::ExampleUseOfErrorSyntax>* 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
