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

// fidl_experiment = output_index_json

#pragma once

#include <test/errorsyntax/parent/cpp/fidl.h>

#include "lib/fidl/cpp/internal/header.h"
namespace test {
namespace errorsyntax {

//
// Domain objects declarations
//

class ExampleUseOfErrorSyntaxCallWhichMayFailRequest;

class ExampleUseOfErrorSyntax_CallWhichMayFail_Response;

class ExampleUseOfErrorSyntax_CallWhichMayFail_Result;

#ifdef __Fuchsia__

class ExampleUseOfErrorSyntax;
using ExampleUseOfErrorSyntaxHandle = ::fidl::InterfaceHandle<ExampleUseOfErrorSyntax>;

#endif  // __Fuchsia__

class ExampleUseOfErrorSyntaxCallWhichMayFailRequest final {
 public:
  static const fidl_type_t* FidlType;

  ::std::string s;

  static inline ::std::unique_ptr<ExampleUseOfErrorSyntaxCallWhichMayFailRequest> New() { return ::std::make_unique<ExampleUseOfErrorSyntaxCallWhichMayFailRequest>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExampleUseOfErrorSyntaxCallWhichMayFailRequest* value, size_t _offset);
  zx_status_t Clone(ExampleUseOfErrorSyntaxCallWhichMayFailRequest* result) const;
};

inline zx_status_t Clone(const ::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest& _value,
                         ::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest* _result) {
  return _value.Clone(_result);
}

using ExampleUseOfErrorSyntaxCallWhichMayFailRequestPtr = ::std::unique_ptr<ExampleUseOfErrorSyntaxCallWhichMayFailRequest>;

class ExampleUseOfErrorSyntax_CallWhichMayFail_Response final {
 public:
  static const fidl_type_t* FidlType;
  ExampleUseOfErrorSyntax_CallWhichMayFail_Response() = default;
  explicit ExampleUseOfErrorSyntax_CallWhichMayFail_Response(int64_t v) : value(std::move(v)) {}
  int64_t ResultValue_() { return std::move(value); }
  explicit ExampleUseOfErrorSyntax_CallWhichMayFail_Response(::std::tuple<int64_t> _value_tuple) {
    std::tie(value) = std::move(_value_tuple);
  }
  operator ::std::tuple<int64_t>() && {
    return std::make_tuple(std::move(value));
  }

  int64_t value{};

  static inline ::std::unique_ptr<ExampleUseOfErrorSyntax_CallWhichMayFail_Response> New() { return ::std::make_unique<ExampleUseOfErrorSyntax_CallWhichMayFail_Response>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExampleUseOfErrorSyntax_CallWhichMayFail_Response* value, size_t _offset);
  zx_status_t Clone(ExampleUseOfErrorSyntax_CallWhichMayFail_Response* result) const;
};

inline zx_status_t Clone(const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response& _value,
                         ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response* _result) {
  return _value.Clone(_result);
}

using ExampleUseOfErrorSyntax_CallWhichMayFail_ResponsePtr = ::std::unique_ptr<ExampleUseOfErrorSyntax_CallWhichMayFail_Response>;

class ExampleUseOfErrorSyntax_CallWhichMayFail_Result final {
 public:
  static const fidl_type_t* FidlType;

  ExampleUseOfErrorSyntax_CallWhichMayFail_Result();
  ~ExampleUseOfErrorSyntax_CallWhichMayFail_Result();

  ExampleUseOfErrorSyntax_CallWhichMayFail_Result(ExampleUseOfErrorSyntax_CallWhichMayFail_Result&&);
  ExampleUseOfErrorSyntax_CallWhichMayFail_Result& operator=(ExampleUseOfErrorSyntax_CallWhichMayFail_Result&&);

  static ExampleUseOfErrorSyntax_CallWhichMayFail_Result WithResponse(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response&&);
  static ExampleUseOfErrorSyntax_CallWhichMayFail_Result WithErr(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<ExampleUseOfErrorSyntax_CallWhichMayFail_Result> New() { return ::std::make_unique<ExampleUseOfErrorSyntax_CallWhichMayFail_Result>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ExampleUseOfErrorSyntax_CallWhichMayFail_Result* value, size_t offset);
  zx_status_t Clone(ExampleUseOfErrorSyntax_CallWhichMayFail_Result* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_response() const { return tag_ == ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::kResponse; }

  ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response& response() {
    EnsureStorageInitialized(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::kResponse);
    return response_;
  }

  const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  ExampleUseOfErrorSyntax_CallWhichMayFail_Result& set_response(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response value);

  bool is_err() const { return tag_ == ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::kErr; }

  uint32_t& err() {
    EnsureStorageInitialized(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::kErr);
    return err_;
  }

  const uint32_t& err() const {
    ZX_ASSERT(is_err());
    return err_;
  }
  ExampleUseOfErrorSyntax_CallWhichMayFail_Result& set_err(uint32_t value);

  ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag Which() const {
    return ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result>;
  ExampleUseOfErrorSyntax_CallWhichMayFail_Result(fpromise::ok_result<int64_t>&& result) {
    set_response(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response{std::move(result.value)});
  }
  ExampleUseOfErrorSyntax_CallWhichMayFail_Result(fpromise::error_result<uint32_t>&& result) {
    set_err(std::move(result.error));
  }
  ExampleUseOfErrorSyntax_CallWhichMayFail_Result(fpromise::result<int64_t, uint32_t>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response{result.take_value()});
    } else {
      set_err(result.take_error());
    }
  }
  operator fpromise::result<int64_t, uint32_t>() && {
    if (is_err()) {
      return fpromise::error(err());
    }
    ::std::tuple<int64_t> value_tuple = std::move(response());
    return fpromise::ok(std::move(std::get<0>(value_tuple)));
  }

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::Invalid);
  union {
    ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response response_;
    uint32_t err_;
  };
};

inline zx_status_t Clone(const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result& value,
                         ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result* result) {
  return value.Clone(result);
}

using ExampleUseOfErrorSyntax_CallWhichMayFail_ResultPtr = ::std::unique_ptr<ExampleUseOfErrorSyntax_CallWhichMayFail_Result>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_errorsyntax_parent_ParentUsesErrorSyntaxComposedCallWhichMayFailRequestTable;

__LOCAL extern "C" const fidl_type_t test_errorsyntax_ExampleUseOfErrorSyntaxCallWhichMayFailRequestTable;

}  // namespace _internal

class ExampleUseOfErrorSyntax_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ComposedCallWhichMayFail(::fidl::MessageEncoder* _encoder, ::std::string* s) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, s, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage CallWhichMayFail(::fidl::MessageEncoder* _encoder, ::std::string* s) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, s, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_errorsyntax_parent_ParentUsesErrorSyntax_ComposedCallWhichMayFail_ResultTable;

__LOCAL extern "C" const fidl_type_t test_errorsyntax_ExampleUseOfErrorSyntax_CallWhichMayFail_ResultTable;

}  // namespace _internal

class ExampleUseOfErrorSyntax_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ComposedCallWhichMayFail(::fidl::MessageEncoder* _encoder, ::test::errorsyntax::parent::ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result* ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage CallWhichMayFail(::fidl::MessageEncoder* _encoder, ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result* ExampleUseOfErrorSyntax_CallWhichMayFail_Result) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ExampleUseOfErrorSyntax_CallWhichMayFail_Result, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__

}  // namespace errorsyntax
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest>
    : public EncodableCodingTraits<::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest, 16> {};

template <>
struct HasPadding<::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest> : public internal::BoolConstant<
                                                                                                     !HasPadding<::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest>::value && IsMemcpyCompatible<::std::string>::value> {};

inline zx_status_t Clone(const ::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest& value,
                         ::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest* result) {
  return ::test::errorsyntax::Clone(value, result);
}

template <>
struct Equality<::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest> {
  bool operator()(const ::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest& _lhs, const ::test::errorsyntax::ExampleUseOfErrorSyntaxCallWhichMayFailRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.s, _rhs.s)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response>
    : public EncodableCodingTraits<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response, 8> {};

template <>
struct IsMemcpyCompatible<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response> : public internal::BoolConstant<
                                                                                                        !HasPadding<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response>::value && IsMemcpyCompatible<int64_t>::value> {};

inline zx_status_t Clone(const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response& value,
                         ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response* result) {
  return ::test::errorsyntax::Clone(value, result);
}

template <>
struct Equality<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response> {
  bool operator()(const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response& _lhs, const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Response& _rhs) const {
    if (!::fidl::Equals(_lhs.value, _rhs.value)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result> : public std::true_type{};

template <>
struct CodingTraits<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result>
    : public EncodableCodingTraits<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result);

    ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result& value,
                         ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result* result) {
  return ::test::errorsyntax::Clone(value, result);
}

template <>
struct Equality<::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result> {
  bool operator()(const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result& _lhs, const ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::Invalid):
        return true;
      case ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::kResponse:
        return ::fidl::Equals(_lhs.response_, _rhs.response_);
      case ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result::Tag::kErr:
        return ::fidl::Equals(_lhs.err_, _rhs.err_);

      default:
        return false;
    }
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace errorsyntax {

#ifdef __Fuchsia__

using ExampleUseOfErrorSyntaxPtr = ::fidl::InterfacePtr<ExampleUseOfErrorSyntax>;
class ExampleUseOfErrorSyntax_Proxy;
class ExampleUseOfErrorSyntax_Stub;
class ExampleUseOfErrorSyntax_EventSender;
class ExampleUseOfErrorSyntax_Sync;
using ExampleUseOfErrorSyntaxSyncPtr = ::fidl::SynchronousInterfacePtr<ExampleUseOfErrorSyntax>;
class ExampleUseOfErrorSyntax_SyncProxy;

namespace internal {

constexpr uint64_t kExampleUseOfErrorSyntax_ComposedCallWhichMayFail_Ordinal = 0x3179cf8f46814221lu;

constexpr ::fidl::MessageDynamicFlags kExampleUseOfErrorSyntax_ComposedCallWhichMayFail_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

constexpr uint64_t kExampleUseOfErrorSyntax_CallWhichMayFail_Ordinal = 0x3424ff83ce3004a2lu;

constexpr ::fidl::MessageDynamicFlags kExampleUseOfErrorSyntax_CallWhichMayFail_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class ExampleUseOfErrorSyntax {
 public:
  using Proxy_ = ::test::errorsyntax::ExampleUseOfErrorSyntax_Proxy;
  using Stub_ = ::test::errorsyntax::ExampleUseOfErrorSyntax_Stub;
  using EventSender_ = ::test::errorsyntax::ExampleUseOfErrorSyntax_EventSender;
  using Sync_ = ::test::errorsyntax::ExampleUseOfErrorSyntax_Sync;
  virtual ~ExampleUseOfErrorSyntax();
  using ComposedCallWhichMayFailCallback =
      fit::function<void(::test::errorsyntax::parent::ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result)>;

  virtual void ComposedCallWhichMayFail(::std::string s, ComposedCallWhichMayFailCallback callback) = 0;
  using CallWhichMayFailCallback =
      fit::function<void(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result)>;

  virtual void CallWhichMayFail(::std::string s, CallWhichMayFailCallback callback) = 0;
};

class ExampleUseOfErrorSyntax_RequestDecoder {
 public:
  ExampleUseOfErrorSyntax_RequestDecoder() = default;
  virtual ~ExampleUseOfErrorSyntax_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response, bool* is_known);
  virtual void ComposedCallWhichMayFail(::std::string s) = 0;
  virtual void CallWhichMayFail(::std::string s) = 0;
};

class ExampleUseOfErrorSyntax_ResponseDecoder {
 public:
  ExampleUseOfErrorSyntax_ResponseDecoder() = default;
  virtual ~ExampleUseOfErrorSyntax_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void ComposedCallWhichMayFail(::test::errorsyntax::parent::ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result) = 0;
  virtual void CallWhichMayFail(::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result ExampleUseOfErrorSyntax_CallWhichMayFail_Result) = 0;
};

class ExampleUseOfErrorSyntax_EventSender {
 public:
  virtual ~ExampleUseOfErrorSyntax_EventSender();
};

class ExampleUseOfErrorSyntax_Sync {
 public:
  using Proxy_ = ::test::errorsyntax::ExampleUseOfErrorSyntax_SyncProxy;
  virtual ~ExampleUseOfErrorSyntax_Sync();
  virtual zx_status_t ComposedCallWhichMayFail(::std::string s, ::test::errorsyntax::parent::ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result* out_ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result) = 0;
  virtual zx_status_t CallWhichMayFail(::std::string s, ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result* out_ExampleUseOfErrorSyntax_CallWhichMayFail_Result) = 0;
};

class ExampleUseOfErrorSyntax_Proxy final : public ::fidl::internal::Proxy, public ExampleUseOfErrorSyntax {
 public:
  explicit ExampleUseOfErrorSyntax_Proxy(::fidl::internal::ProxyController* controller);
  ~ExampleUseOfErrorSyntax_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.errorsyntax/ExampleUseOfErrorSyntax.ComposedCallWhichMayFail
  void ComposedCallWhichMayFail(::std::string s, ComposedCallWhichMayFailCallback callback) override;
  // cts-coverage-fidl-name:test.errorsyntax/ExampleUseOfErrorSyntax.CallWhichMayFail
  void CallWhichMayFail(::std::string s, CallWhichMayFailCallback callback) override;

 private:
  ExampleUseOfErrorSyntax_Proxy(const ::test::errorsyntax::ExampleUseOfErrorSyntax_Proxy&) = delete;
  ExampleUseOfErrorSyntax_Proxy& operator=(const ::test::errorsyntax::ExampleUseOfErrorSyntax_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class ExampleUseOfErrorSyntax_Stub final : public ::fidl::internal::Stub, public ::test::errorsyntax::ExampleUseOfErrorSyntax_EventSender {
 public:
  typedef class ::test::errorsyntax::ExampleUseOfErrorSyntax ExampleUseOfErrorSyntax_clazz;
  explicit ExampleUseOfErrorSyntax_Stub(::test::errorsyntax::ExampleUseOfErrorSyntax_Stub::ExampleUseOfErrorSyntax_clazz* impl);
  ~ExampleUseOfErrorSyntax_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::test::errorsyntax::ExampleUseOfErrorSyntax_Stub::ExampleUseOfErrorSyntax_clazz* impl_;
};

class ExampleUseOfErrorSyntax_SyncProxy : public ::test::errorsyntax::ExampleUseOfErrorSyntax_Sync {
 public:
  explicit ExampleUseOfErrorSyntax_SyncProxy(::zx::channel channel);
  ~ExampleUseOfErrorSyntax_SyncProxy() override;
  // cts-coverage-fidl-name:test.errorsyntax/ExampleUseOfErrorSyntax.ComposedCallWhichMayFail
  zx_status_t ComposedCallWhichMayFail(::std::string s, ::test::errorsyntax::parent::ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result* out_ParentUsesErrorSyntax_ComposedCallWhichMayFail_Result) override;
  // cts-coverage-fidl-name:test.errorsyntax/ExampleUseOfErrorSyntax.CallWhichMayFail
  zx_status_t CallWhichMayFail(::std::string s, ::test::errorsyntax::ExampleUseOfErrorSyntax_CallWhichMayFail_Result* out_ExampleUseOfErrorSyntax_CallWhichMayFail_Result) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<ExampleUseOfErrorSyntax>;
};

#endif  // __Fuchsia__

}  // namespace errorsyntax
}  // namespace test
