// 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 nullable {

//
// Domain objects declarations
//

class StructWithNullableString;

class StructWithNullableVector;

class StructWithNullableHandle;

class SimpleProtocolAddRequest;

class SimpleProtocolAddResponse;

#ifdef __Fuchsia__

class SimpleProtocol;
using SimpleProtocolHandle = ::fidl::InterfaceHandle<SimpleProtocol>;

#endif  // __Fuchsia__

class StructWithNullableProtocol;

class StructWithNullableRequest;

class Int32Wrapper;

class StructWithNullableStruct;

class SimpleUnion;

class StructWithNullableUnion;

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

  ::fidl::StringPtr val;

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

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

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

using StructWithNullableStringPtr = ::std::unique_ptr<StructWithNullableString>;

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

  ::fidl::VectorPtr<int32_t> val;

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

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

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

using StructWithNullableVectorPtr = ::std::unique_ptr<StructWithNullableVector>;

#ifdef __Fuchsia__

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

  ::zx::vmo val;

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

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

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

using StructWithNullableHandlePtr = ::std::unique_ptr<StructWithNullableHandle>;

#endif  // __Fuchsia__

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

  int32_t a{};

  int32_t b{};

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

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

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

using SimpleProtocolAddRequestPtr = ::std::unique_ptr<SimpleProtocolAddRequest>;

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

  int32_t sum{};

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

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

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

using SimpleProtocolAddResponsePtr = ::std::unique_ptr<SimpleProtocolAddResponse>;

#ifdef __Fuchsia__

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

}  // namespace _internal

class SimpleProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Add(::fidl::MessageEncoder* _encoder, int32_t* a, int32_t* b) {
    _encoder->Alloc(8);
    ::fidl::Encode(_encoder, a, 0 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, b, 4 + sizeof(fidl_message_header_t));

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

}  // namespace _internal

class SimpleProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Add(::fidl::MessageEncoder* _encoder, int32_t* sum) {
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, sum, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceHandle<::test::nullable::SimpleProtocol> val;

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

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

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

using StructWithNullableProtocolPtr = ::std::unique_ptr<StructWithNullableProtocol>;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceRequest<::test::nullable::SimpleProtocol> val;

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

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

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

using StructWithNullableRequestPtr = ::std::unique_ptr<StructWithNullableRequest>;

#endif  // __Fuchsia__

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

  int32_t val{};

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

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

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

using Int32WrapperPtr = ::std::unique_ptr<Int32Wrapper>;

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

  ::std::unique_ptr<::test::nullable::Int32Wrapper> val;

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

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

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

using StructWithNullableStructPtr = ::std::unique_ptr<StructWithNullableStruct>;

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

  SimpleUnion();
  ~SimpleUnion();

  SimpleUnion(SimpleUnion&&);
  SimpleUnion& operator=(SimpleUnion&&);

  static SimpleUnion WithA(int32_t&&);
  static SimpleUnion WithB(float&&);

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

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

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

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

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

  bool is_a() const { return tag_ == ::test::nullable::SimpleUnion::Tag::kA; }

  int32_t& a() {
    EnsureStorageInitialized(::test::nullable::SimpleUnion::Tag::kA);
    return a_;
  }

  const int32_t& a() const {
    ZX_ASSERT(is_a());
    return a_;
  }
  SimpleUnion& set_a(int32_t value);

  bool is_b() const { return tag_ == ::test::nullable::SimpleUnion::Tag::kB; }

  float& b() {
    EnsureStorageInitialized(::test::nullable::SimpleUnion::Tag::kB);
    return b_;
  }

  const float& b() const {
    ZX_ASSERT(is_b());
    return b_;
  }
  SimpleUnion& set_b(float value);

  ::test::nullable::SimpleUnion::Tag Which() const {
    return ::test::nullable::SimpleUnion::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::nullable::SimpleUnion>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::nullable::SimpleUnion::Tag::Invalid);
  union {
    int32_t a_;
    float b_;
  };
};

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

using SimpleUnionPtr = ::std::unique_ptr<SimpleUnion>;

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

  ::std::unique_ptr<::test::nullable::SimpleUnion> val;

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

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

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

using StructWithNullableUnionPtr = ::std::unique_ptr<StructWithNullableUnion>;

}  // namespace nullable
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::nullable::StructWithNullableString>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableString, 16> {};

template <>
struct HasPadding<::test::nullable::StructWithNullableString> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableString> : public internal::BoolConstant<
                                                                            !HasPadding<::test::nullable::StructWithNullableString>::value && IsMemcpyCompatible<::fidl::StringPtr>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableString> {
  bool operator()(const ::test::nullable::StructWithNullableString& _lhs, const ::test::nullable::StructWithNullableString& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::nullable::StructWithNullableVector>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableVector, 16> {};

template <>
struct HasPadding<::test::nullable::StructWithNullableVector> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableVector> : public internal::BoolConstant<
                                                                            !HasPadding<::test::nullable::StructWithNullableVector>::value && IsMemcpyCompatible<::fidl::VectorPtr<int32_t>>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableVector> {
  bool operator()(const ::test::nullable::StructWithNullableVector& _lhs, const ::test::nullable::StructWithNullableVector& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::nullable::StructWithNullableHandle>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableHandle, 4> {};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableHandle> : public internal::BoolConstant<
                                                                            !HasPadding<::test::nullable::StructWithNullableHandle>::value && IsMemcpyCompatible<::zx::vmo>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableHandle> {
  bool operator()(const ::test::nullable::StructWithNullableHandle& _lhs, const ::test::nullable::StructWithNullableHandle& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};

#endif  // __Fuchsia__

template <>
struct CodingTraits<::test::nullable::SimpleProtocolAddRequest>
    : public EncodableCodingTraits<::test::nullable::SimpleProtocolAddRequest, 8> {};

template <>
struct IsMemcpyCompatible<::test::nullable::SimpleProtocolAddRequest> : public internal::BoolConstant<
                                                                            !HasPadding<::test::nullable::SimpleProtocolAddRequest>::value && IsMemcpyCompatible<int32_t>::value> {};

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

template <>
struct Equality<::test::nullable::SimpleProtocolAddRequest> {
  bool operator()(const ::test::nullable::SimpleProtocolAddRequest& _lhs, const ::test::nullable::SimpleProtocolAddRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::nullable::SimpleProtocolAddResponse>
    : public EncodableCodingTraits<::test::nullable::SimpleProtocolAddResponse, 4> {};

template <>
struct IsMemcpyCompatible<::test::nullable::SimpleProtocolAddResponse> : public internal::BoolConstant<
                                                                             !HasPadding<::test::nullable::SimpleProtocolAddResponse>::value && IsMemcpyCompatible<int32_t>::value> {};

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

template <>
struct Equality<::test::nullable::SimpleProtocolAddResponse> {
  bool operator()(const ::test::nullable::SimpleProtocolAddResponse& _lhs, const ::test::nullable::SimpleProtocolAddResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.sum, _rhs.sum)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::nullable::StructWithNullableProtocol>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableProtocol, 4> {};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableProtocol> : public internal::BoolConstant<
                                                                              !HasPadding<::test::nullable::StructWithNullableProtocol>::value && IsMemcpyCompatible<::fidl::InterfaceHandle<::test::nullable::SimpleProtocol>>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableProtocol> {
  bool operator()(const ::test::nullable::StructWithNullableProtocol& _lhs, const ::test::nullable::StructWithNullableProtocol& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::nullable::StructWithNullableRequest>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableRequest> : public internal::BoolConstant<
                                                                             !HasPadding<::test::nullable::StructWithNullableRequest>::value && IsMemcpyCompatible<::fidl::InterfaceRequest<::test::nullable::SimpleProtocol>>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableRequest> {
  bool operator()(const ::test::nullable::StructWithNullableRequest& _lhs, const ::test::nullable::StructWithNullableRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};

#endif  // __Fuchsia__

template <>
struct CodingTraits<::test::nullable::Int32Wrapper>
    : public EncodableCodingTraits<::test::nullable::Int32Wrapper, 4> {};

template <>
struct IsMemcpyCompatible<::test::nullable::Int32Wrapper> : public internal::BoolConstant<
                                                                !HasPadding<::test::nullable::Int32Wrapper>::value && IsMemcpyCompatible<int32_t>::value> {};

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

template <>
struct Equality<::test::nullable::Int32Wrapper> {
  bool operator()(const ::test::nullable::Int32Wrapper& _lhs, const ::test::nullable::Int32Wrapper& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::nullable::StructWithNullableStruct>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableStruct, 8> {};

template <>
struct HasPadding<::test::nullable::StructWithNullableStruct> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableStruct> : public internal::BoolConstant<
                                                                            !HasPadding<::test::nullable::StructWithNullableStruct>::value && IsMemcpyCompatible<::std::unique_ptr<::test::nullable::Int32Wrapper>>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableStruct> {
  bool operator()(const ::test::nullable::StructWithNullableStruct& _lhs, const ::test::nullable::StructWithNullableStruct& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::nullable::SimpleUnion> : public std::true_type{};

template <>
struct CodingTraits<::test::nullable::SimpleUnion>
    : public EncodableCodingTraits<::test::nullable::SimpleUnion, 16> {};

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

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

    ::test::nullable::SimpleUnion::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::nullable::SimpleUnion::Tag::Invalid):
        return true;
      case ::test::nullable::SimpleUnion::Tag::kA:
        return ::fidl::Equals(_lhs.a_, _rhs.a_);
      case ::test::nullable::SimpleUnion::Tag::kB:
        return ::fidl::Equals(_lhs.b_, _rhs.b_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::nullable::StructWithNullableUnion>
    : public EncodableCodingTraits<::test::nullable::StructWithNullableUnion, 16> {};

template <>
struct IsMemcpyCompatible<::test::nullable::StructWithNullableUnion> : public internal::BoolConstant<
                                                                           !HasPadding<::test::nullable::StructWithNullableUnion>::value && IsMemcpyCompatible<::std::unique_ptr<::test::nullable::SimpleUnion>>::value> {};

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

template <>
struct Equality<::test::nullable::StructWithNullableUnion> {
  bool operator()(const ::test::nullable::StructWithNullableUnion& _lhs, const ::test::nullable::StructWithNullableUnion& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};

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

#ifdef __Fuchsia__

using SimpleProtocolPtr = ::fidl::InterfacePtr<SimpleProtocol>;
class SimpleProtocol_Proxy;
class SimpleProtocol_Stub;
class SimpleProtocol_EventSender;
class SimpleProtocol_Sync;
using SimpleProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<SimpleProtocol>;
class SimpleProtocol_SyncProxy;

namespace internal {

constexpr uint64_t kSimpleProtocol_Add_Ordinal = 0x7ee19cf19ae30276lu;

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class SimpleProtocol {
 public:
  using Proxy_ = ::test::nullable::SimpleProtocol_Proxy;
  using Stub_ = ::test::nullable::SimpleProtocol_Stub;
  using EventSender_ = ::test::nullable::SimpleProtocol_EventSender;
  using Sync_ = ::test::nullable::SimpleProtocol_Sync;
  virtual ~SimpleProtocol();
  using AddCallback =
      fit::function<void(int32_t)>;

  virtual void Add(int32_t a, int32_t b, AddCallback callback) = 0;
};

class SimpleProtocol_RequestDecoder {
 public:
  SimpleProtocol_RequestDecoder() = default;
  virtual ~SimpleProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response, bool* is_known);
  virtual void Add(int32_t a, int32_t b) = 0;
};

class SimpleProtocol_ResponseDecoder {
 public:
  SimpleProtocol_ResponseDecoder() = default;
  virtual ~SimpleProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void Add(int32_t sum) = 0;
};

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

class SimpleProtocol_Sync {
 public:
  using Proxy_ = ::test::nullable::SimpleProtocol_SyncProxy;
  virtual ~SimpleProtocol_Sync();
  virtual zx_status_t Add(int32_t a, int32_t b, int32_t* out_sum) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.nullable/SimpleProtocol.Add
  void Add(int32_t a, int32_t b, AddCallback callback) override;

 private:
  SimpleProtocol_Proxy(const ::test::nullable::SimpleProtocol_Proxy&) = delete;
  SimpleProtocol_Proxy& operator=(const ::test::nullable::SimpleProtocol_Proxy&) = delete;

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

class SimpleProtocol_Stub final : public ::fidl::internal::Stub, public ::test::nullable::SimpleProtocol_EventSender {
 public:
  typedef class ::test::nullable::SimpleProtocol SimpleProtocol_clazz;
  explicit SimpleProtocol_Stub(::test::nullable::SimpleProtocol_Stub::SimpleProtocol_clazz* impl);
  ~SimpleProtocol_Stub() override;

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

 private:
  ::test::nullable::SimpleProtocol_Stub::SimpleProtocol_clazz* impl_;
};

class SimpleProtocol_SyncProxy : public ::test::nullable::SimpleProtocol_Sync {
 public:
  explicit SimpleProtocol_SyncProxy(::zx::channel channel);
  ~SimpleProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.nullable/SimpleProtocol.Add
  zx_status_t Add(int32_t a, int32_t b, int32_t* out_sum) override;

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

#endif  // __Fuchsia__

}  // namespace nullable
}  // namespace test
