// 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/channel.h>

#endif  // __Fuchsia__

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

namespace test_versions {
namespace wire {
using Bits = ::test_versions::Bits;

using Enum = ::test_versions::Enum;

struct Struct;

class Table;

class Union;

extern "C" const fidl_type_t test_versions_StructTable;

struct Struct {
  uint32_t x = {};
};

}  // namespace wire
}  // namespace test_versions
template <>
class ::fidl::WireTableBuilder<::test_versions::wire::Table>;
template <>
class ::fidl::WireTableExternalBuilder<::test_versions::wire::Table>;

template <>
struct ::fidl::WireTableFrame<::test_versions::wire::Table> 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<uint32_t> x_;

  friend class ::test_versions::wire::Table;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_versions::wire::Table,
      ::fidl::WireTableBuilder<::test_versions::wire::Table>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_versions::wire::Table,
      ::fidl::WireTableExternalBuilder<::test_versions::wire::Table>>;
};

namespace test_versions {
namespace wire {
extern "C" const fidl_type_t test_versions_TableTable;

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

  ~Table() = default;

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

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

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

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

  const uint32_t& x() const {
    ZX_ASSERT(has_x());
    return frame_ptr_->x_.get_data();
  }
  uint32_t& x() {
    ZX_ASSERT(has_x());
    return frame_ptr_->x_.get_data();
  }
  bool has_x() const { return max_ordinal_ >= 1 && frame_ptr_->x_.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

  Table& set_x(uint32_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  Table& clear_x() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.clear_data();
    return *this;
  }

  explicit Table(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<
                   ::fidl::WireTableFrame<::test_versions::wire::Table>>(
            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 Table(
      ::fidl::ObjectView<::fidl::WireTableFrame<::test_versions::wire::Table>>&&
          frame)
      : frame_ptr_(std::move(frame)) {}

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_versions::wire::Table,
      ::fidl::WireTableBuilder<::test_versions::wire::Table>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_versions::wire::Table,
      ::fidl::WireTableExternalBuilder<::test_versions::wire::Table>>;

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

  BuilderImpl& x(uint32_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->x_.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_versions::wire::Table>>&&
          frame)
      : table_(std::move(frame)) {}

 private:
  ::test_versions::wire::Table table_;
};

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

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

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

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

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

extern "C" const fidl_type_t test_versions_UnionTable;

class Union {
 public:
  Union()
      : ordinal_(::test_versions::wire::Union::Ordinal::Invalid), envelope_{} {}

  Union(const Union&) = default;
  Union& operator=(const Union&) = default;
  Union(Union&&) = default;
  Union& operator=(Union&&) = default;

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

  bool has_invalid_tag() const {
    return ordinal_ == ::test_versions::wire::Union::Ordinal::Invalid;
  }

  bool is_x() const {
    return ordinal_ == ::test_versions::wire::Union::Ordinal::kX;
  }

  static Union WithX(uint32_t val) {
    Union result;
    result.ordinal_ = ::test_versions::wire::Union::Ordinal::kX;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& x() {
    ZX_ASSERT(ordinal_ == ::test_versions::wire::Union::Ordinal::kX);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& x() const {
    ZX_ASSERT(ordinal_ == ::test_versions::wire::Union::Ordinal::kX);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_versions::wire::Union::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kX = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_versions::wire::Union::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

constexpr uint32_t kConst = 0u;

constexpr bool kAddedAtHead = true;

}  // namespace wire
}  // namespace test_versions
namespace fidl {

template <>
struct TypeTraits<::test_versions::wire::Struct> {
  static constexpr const fidl_type_t* kType =
      &::test_versions::wire::test_versions_StructTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kPrimarySizeV1 = 4;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_versions::wire::Struct> : public std::true_type {};
template <>
struct IsStruct<::test_versions::wire::Struct> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_versions::wire::Struct>);
static_assert(offsetof(::test_versions::wire::Struct, x) == 0);
static_assert(sizeof(::test_versions::wire::Struct) ==
              TypeTraits<::test_versions::wire::Struct>::kPrimarySize);

template <>
struct TypeTraits<::test_versions::wire::Table> {
  static constexpr const fidl_type_t* kType =
      &::test_versions::wire::test_versions_TableTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  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_versions::wire::Table> : public std::true_type {};
template <>
struct IsTable<::test_versions::wire::Table> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_versions::wire::Table>);

template <>
struct TypeTraits<::test_versions::wire::Union> {
  static constexpr const fidl_type_t* kType =
      &::test_versions::wire::test_versions_UnionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  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_versions::wire::Union> : public std::true_type {};
template <>
struct IsUnion<::test_versions::wire::Union> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_versions::wire::Union>);

}  // namespace fidl
