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

// fidl_experiment = output_index_json

#pragma once

#include "lib/fidl/cpp/internal/header.h"

namespace test {
namespace error {

//
// Domain objects declarations
//

class ExampleFooRequest;

class Example_foo_Response;

class Example_foo_Result;

#ifdef __Fuchsia__

class Example;
using ExampleHandle = ::fidl::InterfaceHandle<Example>;

#endif  // __Fuchsia__

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

  ::std::string s;

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

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

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

using ExampleFooRequestPtr = ::std::unique_ptr<ExampleFooRequest>;

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

  int64_t y{};

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

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

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

using Example_foo_ResponsePtr = ::std::unique_ptr<Example_foo_Response>;

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

  Example_foo_Result();
  ~Example_foo_Result();

  Example_foo_Result(Example_foo_Result&&);
  Example_foo_Result& operator=(Example_foo_Result&&);

  static Example_foo_Result WithResponse(::test::error::Example_foo_Response&&);
  static Example_foo_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<Example_foo_Result> New() { return ::std::make_unique<Example_foo_Result>(); }

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

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

  bool is_response() const { return tag_ == ::test::error::Example_foo_Result::Tag::kResponse; }

  ::test::error::Example_foo_Response& response() {
    EnsureStorageInitialized(::test::error::Example_foo_Result::Tag::kResponse);
    return response_;
  }

  const ::test::error::Example_foo_Response& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  Example_foo_Result& set_response(::test::error::Example_foo_Response value);

  bool is_err() const { return tag_ == ::test::error::Example_foo_Result::Tag::kErr; }

  uint32_t& err() {
    EnsureStorageInitialized(::test::error::Example_foo_Result::Tag::kErr);
    return err_;
  }

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

  ::test::error::Example_foo_Result::Tag Which() const {
    return ::test::error::Example_foo_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::error::Example_foo_Result>;
  Example_foo_Result(fpromise::ok_result<int64_t>&& result) {
    set_response(::test::error::Example_foo_Response{std::move(result.value)});
  }
  Example_foo_Result(fpromise::error_result<uint32_t>&& result) {
    set_err(std::move(result.error));
  }
  Example_foo_Result(fpromise::result<int64_t, uint32_t>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(::test::error::Example_foo_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::error::Example_foo_Result::Tag::Invalid);
  union {
    ::test::error::Example_foo_Response response_;
    uint32_t err_;
  };
};

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

using Example_foo_ResultPtr = ::std::unique_ptr<Example_foo_Result>;

#ifdef __Fuchsia__

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

}  // namespace _internal

class Example_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage foo(::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_error_Example_foo_ResultTable;

}  // namespace _internal

class Example_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage foo(::fidl::MessageEncoder* _encoder, ::test::error::Example_foo_Result* Example_foo_Result) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, Example_foo_Result, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__

}  // namespace error
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::error::ExampleFooRequest>
    : public EncodableCodingTraits<::test::error::ExampleFooRequest, 16> {};

template <>
struct HasPadding<::test::error::ExampleFooRequest> : public std::true_type{};

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

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

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

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

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

template <>
struct Equality<::test::error::Example_foo_Response> {
  bool operator()(const ::test::error::Example_foo_Response& _lhs, const ::test::error::Example_foo_Response& _rhs) const {
    if (!::fidl::Equals(_lhs.y, _rhs.y)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::error::Example_foo_Result> : public std::true_type{};

template <>
struct CodingTraits<::test::error::Example_foo_Result>
    : public EncodableCodingTraits<::test::error::Example_foo_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::error::Example_foo_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::error::Example_foo_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::error::Example_foo_Result);

    ::test::error::Example_foo_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

      default:
        return false;
    }
  }
};

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

#ifdef __Fuchsia__

using ExamplePtr = ::fidl::InterfacePtr<Example>;
class Example_Proxy;
class Example_Stub;
class Example_EventSender;
class Example_Sync;
using ExampleSyncPtr = ::fidl::SynchronousInterfacePtr<Example>;
class Example_SyncProxy;

namespace internal {

constexpr uint64_t kExample_foo_Ordinal = 0xf5f1179dc411e44lu;

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Example {
 public:
  using Proxy_ = ::test::error::Example_Proxy;
  using Stub_ = ::test::error::Example_Stub;
  using EventSender_ = ::test::error::Example_EventSender;
  using Sync_ = ::test::error::Example_Sync;
  virtual ~Example();
  using fooCallback =
      fit::function<void(::test::error::Example_foo_Result)>;

  virtual void foo(::std::string s, fooCallback callback) = 0;
};

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

class Example_ResponseDecoder {
 public:
  Example_ResponseDecoder() = default;
  virtual ~Example_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void foo(::test::error::Example_foo_Result Example_foo_Result) = 0;
};

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

class Example_Sync {
 public:
  using Proxy_ = ::test::error::Example_SyncProxy;
  virtual ~Example_Sync();
  virtual zx_status_t foo(::std::string s, ::test::error::Example_foo_Result* out_Example_foo_Result) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.error/Example.foo
  void foo(::std::string s, fooCallback callback) override;

 private:
  Example_Proxy(const ::test::error::Example_Proxy&) = delete;
  Example_Proxy& operator=(const ::test::error::Example_Proxy&) = delete;

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

class Example_Stub final : public ::fidl::internal::Stub, public ::test::error::Example_EventSender {
 public:
  typedef class ::test::error::Example Example_clazz;
  explicit Example_Stub(::test::error::Example_Stub::Example_clazz* impl);
  ~Example_Stub() override;

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

 private:
  ::test::error::Example_Stub::Example_clazz* impl_;
};

class Example_SyncProxy : public ::test::error::Example_Sync {
 public:
  explicit Example_SyncProxy(::zx::channel channel);
  ~Example_SyncProxy() override;
  // cts-coverage-fidl-name:test.error/Example.foo
  zx_status_t foo(::std::string s, ::test::error::Example_foo_Result* out_Example_foo_Result) override;

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

#endif  // __Fuchsia__

}  // namespace error
}  // namespace test
