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

#pragma once

#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/vmo.h>

#endif  // __Fuchsia__

#include <fidl/test.handlesintypes/cpp/common_types.h>
#include <fidl/test.handlesintypes/cpp/markers.h>

namespace test_handlesintypes {
namespace wire {
using ObjType = ::test_handlesintypes::ObjType;

struct HandlesInTypes;

class TableWithHandle;

class UnionWithHandle;

#ifdef __Fuchsia__

}  // namespace wire
}  // namespace test_handlesintypes
template <>
class ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>;
template <>
class ::fidl::WireTableExternalBuilder<
    ::test_handlesintypes::wire::TableWithHandle>;

template <>
struct ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>
    final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  ::fidl::Envelope<::zx::vmo> h_;

  friend class ::test_handlesintypes::wire::TableWithHandle;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_handlesintypes::wire::TableWithHandle,
      ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_handlesintypes::wire::TableWithHandle,
      ::fidl::WireTableExternalBuilder<
          ::test_handlesintypes::wire::TableWithHandle>>;
};

namespace test_handlesintypes {
namespace wire {
extern "C" const fidl_type_t test_handlesintypes_TableWithHandleTable;

class TableWithHandle {
 public:
  TableWithHandle() = default;
  TableWithHandle(const TableWithHandle& other) noexcept = default;
  TableWithHandle& operator=(const TableWithHandle& other) noexcept = default;
  TableWithHandle(TableWithHandle&& other) noexcept = default;
  TableWithHandle& operator=(TableWithHandle&& other) noexcept = default;

  ~TableWithHandle() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;
  void _CloseHandles();

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>
  Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<
      ::test_handlesintypes::wire::TableWithHandle>
  ExternalBuilder(
      ::fidl::ObjectView<
          ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>>
          frame);

  const ::zx::vmo& h() const {
    ZX_ASSERT(has_h());
    return frame_ptr_->h_.get_data();
  }
  ::zx::vmo& h() {
    ZX_ASSERT(has_h());
    return frame_ptr_->h_.get_data();
  }
  bool has_h() const { return max_ordinal_ >= 1 && frame_ptr_->h_.has_data(); }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  TableWithHandle& set_h(::zx::vmo elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->h_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  TableWithHandle& clear_h() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->h_.clear_data();
    return *this;
  }

  explicit TableWithHandle(::fidl::AnyArena& allocator)
      : frame_ptr_(
            ::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_handlesintypes::wire::TableWithHandle>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or
  // for another table.
  explicit TableWithHandle(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_handlesintypes::wire::TableWithHandle>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<
        ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>>(
        allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<
                ::test_handlesintypes::wire::TableWithHandle>>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_handlesintypes::wire::TableWithHandle,
      ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_handlesintypes::wire::TableWithHandle,
      ::fidl::WireTableExternalBuilder<
          ::test_handlesintypes::wire::TableWithHandle>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<
      ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>>
      frame_ptr_;
};
}  // namespace wire
}  // namespace test_handlesintypes
template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<
    ::test_handlesintypes::wire::TableWithHandle, BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  ::test_handlesintypes::wire::TableWithHandle Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_handlesintypes::wire::TableWithHandle t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  BuilderImpl& h(::zx::vmo elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->h_.set_data(std::move(elem));
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(
      ::fidl::ObjectView<::fidl::WireTableFrame<
          ::test_handlesintypes::wire::TableWithHandle>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_handlesintypes::wire::TableWithHandle table_;
};

template <>
class ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>
    final : public ::fidl::internal::WireTableBaseBuilder<
                ::test_handlesintypes::wire::TableWithHandle,
                ::fidl::WireTableBuilder<
                    ::test_handlesintypes::wire::TableWithHandle>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_handlesintypes::wire::TableWithHandle,
      ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>>;

 public:
 private:
  friend class ::test_handlesintypes::wire::TableWithHandle;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_handlesintypes::wire::TableWithHandle>>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<
    ::test_handlesintypes::wire::TableWithHandle>
    final : public ::fidl::internal::WireTableBaseBuilder<
                ::test_handlesintypes::wire::TableWithHandle,
                ::fidl::WireTableExternalBuilder<
                    ::test_handlesintypes::wire::TableWithHandle>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<
      ::test_handlesintypes::wire::TableWithHandle,
      ::fidl::WireTableExternalBuilder<
          ::test_handlesintypes::wire::TableWithHandle>>;

 private:
  friend class ::test_handlesintypes::wire::TableWithHandle;
  using Base::Base;
  WireTableExternalBuilder(
      ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>*
          frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<
                 ::test_handlesintypes::wire::TableWithHandle>>::
                 FromExternal(frame)) {}
};
namespace test_handlesintypes {
namespace wire {
inline ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>
TableWithHandle::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_handlesintypes::wire::TableWithHandle>(
      arena);
}
inline ::fidl::WireTableExternalBuilder<
    ::test_handlesintypes::wire::TableWithHandle>
TableWithHandle::ExternalBuilder(
    ::fidl::ObjectView<
        ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>>
        frame) {
  return ::fidl::WireTableExternalBuilder<
      ::test_handlesintypes::wire::TableWithHandle>(std::move(frame));
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_UnionWithHandleTable;

class UnionWithHandle {
 public:
  UnionWithHandle()
      : ordinal_(
            ::test_handlesintypes::wire::UnionWithHandle::Ordinal::Invalid),
        envelope_{} {}

  ~UnionWithHandle();
  UnionWithHandle(UnionWithHandle&& other) { _Move(std::move(other)); }
  UnionWithHandle& operator=(UnionWithHandle&& other) {
    if (this != &other) {
      _Move(std::move(other));
    }
    return *this;
  }

  enum class Tag : fidl_xunion_tag_t {
    kH = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_handlesintypes::wire::UnionWithHandle::Ordinal::Invalid;
  }

  bool is_h() const {
    return ordinal_ ==
           ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH;
  }

  static UnionWithHandle WithH(::zx::vmo val) {
    UnionWithHandle result;
    result.ordinal_ = ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH;
    result.envelope_.As<::zx::vmo>().set_data(std::move(val));
    return result;
  }

  ::zx::vmo& h() {
    ZX_ASSERT(ordinal_ ==
              ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH);
    return envelope_.As<::zx::vmo>().get_data();
  }
  const ::zx::vmo& h() const {
    ZX_ASSERT(ordinal_ ==
              ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH);
    return envelope_.As<::zx::vmo>().get_data();
  }
  ::test_handlesintypes::wire::UnionWithHandle::Tag Which() const;
  void _CloseHandles();

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kH = 1,  // 0x1
  };
  void _Move(UnionWithHandle&& other);

  static void SizeAndOffsetAssertionHelper();
  ::test_handlesintypes::wire::UnionWithHandle::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_HandlesInTypesTable;

struct HandlesInTypes {
  ::zx::vmo normal_handle = {};

  ::fidl::VectorView<::zx::vmo> handle_in_vec = {};

  ::fidl::Array<::zx::vmo, 5> handle_in_array = {};

  ::fidl::VectorView<::fidl::Array<::zx::vmo, 5>> handle_in_mixed_vec_array =
      {};

  ::test_handlesintypes::wire::TableWithHandle table_with_handle = {};

  ::test_handlesintypes::wire::UnionWithHandle union_with_handle = {};

  void _CloseHandles();
};
#endif  // __Fuchsia__

}  // namespace wire
}  // namespace test_handlesintypes
namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsResource<::test_handlesintypes::wire::HandlesInTypes>
    : public std::true_type {};

template <>
struct TypeTraits<::test_handlesintypes::wire::HandlesInTypes> {
  static constexpr const fidl_type_t* kType =
      &::test_handlesintypes::wire::test_handlesintypes_HandlesInTypesTable;
  static constexpr uint32_t kMaxNumHandles = 4294967295;
  static constexpr uint32_t kPrimarySize = 96;
  static constexpr uint32_t kPrimarySizeV1 = 104;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_handlesintypes::wire::HandlesInTypes>
    : public std::true_type {};
template <>
struct IsStruct<::test_handlesintypes::wire::HandlesInTypes>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_handlesintypes::wire::HandlesInTypes>);
static_assert(offsetof(::test_handlesintypes::wire::HandlesInTypes,
                       normal_handle) == 0);
static_assert(offsetof(::test_handlesintypes::wire::HandlesInTypes,
                       handle_in_vec) == 8);
static_assert(offsetof(::test_handlesintypes::wire::HandlesInTypes,
                       handle_in_array) == 24);
static_assert(offsetof(::test_handlesintypes::wire::HandlesInTypes,
                       handle_in_mixed_vec_array) == 48);
static_assert(offsetof(::test_handlesintypes::wire::HandlesInTypes,
                       table_with_handle) == 64);
static_assert(offsetof(::test_handlesintypes::wire::HandlesInTypes,
                       union_with_handle) == 80);
static_assert(
    sizeof(::test_handlesintypes::wire::HandlesInTypes) ==
    TypeTraits<::test_handlesintypes::wire::HandlesInTypes>::kPrimarySize);
#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct IsResource<::test_handlesintypes::wire::TableWithHandle>
    : public std::true_type {};

template <>
struct TypeTraits<::test_handlesintypes::wire::TableWithHandle> {
  static constexpr const fidl_type_t* kType =
      &::test_handlesintypes::wire::test_handlesintypes_TableWithHandleTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_handlesintypes::wire::TableWithHandle>
    : public std::true_type {};
template <>
struct IsTable<::test_handlesintypes::wire::TableWithHandle>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_handlesintypes::wire::TableWithHandle>);
#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct IsResource<::test_handlesintypes::wire::UnionWithHandle>
    : public std::true_type {};

template <>
struct TypeTraits<::test_handlesintypes::wire::UnionWithHandle> {
  static constexpr const fidl_type_t* kType =
      &::test_handlesintypes::wire::test_handlesintypes_UnionWithHandleTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_handlesintypes::wire::UnionWithHandle>
    : public std::true_type {};
template <>
struct IsUnion<::test_handlesintypes::wire::UnionWithHandle>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::test_handlesintypes::wire::UnionWithHandle>);
#endif  // __Fuchsia__

}  // namespace fidl
