// 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__

#endif  // __Fuchsia__

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

namespace test_arrays {
namespace wire {
struct StructSmallArray;

struct StructLargeArray;

class TableSmallArray;

class TableLargeArray;

class UnionSmallArray;

class UnionLargeArray;

}  // namespace wire
}  // namespace test_arrays
template <>
class ::fidl::WireTableBuilder<::test_arrays::wire::TableSmallArray>;
template <>
class ::fidl::WireTableExternalBuilder<::test_arrays::wire::TableSmallArray>;

template <>
struct ::fidl::WireTableFrame<::test_arrays::wire::TableSmallArray> 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<::fidl::Array<uint32_t, 2>> a_;

  friend class ::test_arrays::wire::TableSmallArray;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableSmallArray,
      ::fidl::WireTableBuilder<::test_arrays::wire::TableSmallArray>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableSmallArray,
      ::fidl::WireTableExternalBuilder<::test_arrays::wire::TableSmallArray>>;
};

namespace test_arrays {
namespace wire {
extern "C" const fidl_type_t test_arrays_TableSmallArrayTable;

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

  ~TableSmallArray() = 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_arrays::wire::TableSmallArray> Builder(
      ::fidl::AnyArena& arena);

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

  const ::fidl::Array<uint32_t, 2>& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  ::fidl::Array<uint32_t, 2>& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.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

  TableSmallArray& set_a(::fidl::ObjectView<::fidl::Array<uint32_t, 2>> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(elem);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  TableSmallArray& set_a(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(nullptr);
    return *this;
  }
  template <typename... Args>
  TableSmallArray& set_a(::fidl::AnyArena& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(::fidl::ObjectView<::fidl::Array<uint32_t, 2>>(
        allocator, std::forward<Args>(args)...));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  TableSmallArray& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

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

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableSmallArray,
      ::fidl::WireTableBuilder<::test_arrays::wire::TableSmallArray>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableSmallArray,
      ::fidl::WireTableExternalBuilder<::test_arrays::wire::TableSmallArray>>;

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

  BuilderImpl& a(::fidl::ObjectView<::fidl::Array<uint32_t, 2>> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(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_arrays::wire::TableSmallArray>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_arrays::wire::TableSmallArray table_;
};

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

 public:
  using Base::a;

  template <typename... Args>
  ::fidl::WireTableBuilder<::test_arrays::wire::TableSmallArray>& a(
      Args&&... args_) {
    a(::fidl::ObjectView<::fidl::Array<uint32_t, 2>>(
        arena_.get(), std::forward<Args>(args_)...));
    return *this;
  }

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

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

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

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

}  // namespace wire
}  // namespace test_arrays
template <>
class ::fidl::WireTableBuilder<::test_arrays::wire::TableLargeArray>;
template <>
class ::fidl::WireTableExternalBuilder<::test_arrays::wire::TableLargeArray>;

template <>
struct ::fidl::WireTableFrame<::test_arrays::wire::TableLargeArray> 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<::fidl::Array<uint32_t, 100>> a_;

  friend class ::test_arrays::wire::TableLargeArray;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableLargeArray,
      ::fidl::WireTableBuilder<::test_arrays::wire::TableLargeArray>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableLargeArray,
      ::fidl::WireTableExternalBuilder<::test_arrays::wire::TableLargeArray>>;
};

namespace test_arrays {
namespace wire {
extern "C" const fidl_type_t test_arrays_TableLargeArrayTable;

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

  ~TableLargeArray() = 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_arrays::wire::TableLargeArray> Builder(
      ::fidl::AnyArena& arena);

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

  const ::fidl::Array<uint32_t, 100>& a() const {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  ::fidl::Array<uint32_t, 100>& a() {
    ZX_ASSERT(has_a());
    return frame_ptr_->a_.get_data();
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_ptr_->a_.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

  TableLargeArray& set_a(
      ::fidl::ObjectView<::fidl::Array<uint32_t, 100>> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(elem);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  TableLargeArray& set_a(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(nullptr);
    return *this;
  }
  template <typename... Args>
  TableLargeArray& set_a(::fidl::AnyArena& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.set_data(::fidl::ObjectView<::fidl::Array<uint32_t, 100>>(
        allocator, std::forward<Args>(args)...));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  TableLargeArray& clear_a() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->a_.clear_data();
    return *this;
  }

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

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableLargeArray,
      ::fidl::WireTableBuilder<::test_arrays::wire::TableLargeArray>>;
  friend ::fidl::internal::WireTableBaseBuilder<
      ::test_arrays::wire::TableLargeArray,
      ::fidl::WireTableExternalBuilder<::test_arrays::wire::TableLargeArray>>;

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

  BuilderImpl& a(::fidl::ObjectView<::fidl::Array<uint32_t, 100>> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->a_.set_data(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_arrays::wire::TableLargeArray>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_arrays::wire::TableLargeArray table_;
};

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

 public:
  using Base::a;

  template <typename... Args>
  ::fidl::WireTableBuilder<::test_arrays::wire::TableLargeArray>& a(
      Args&&... args_) {
    a(::fidl::ObjectView<::fidl::Array<uint32_t, 100>>(
        arena_.get(), std::forward<Args>(args_)...));
    return *this;
  }

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

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

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

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

extern "C" const fidl_type_t test_arrays_UnionSmallArrayTable;

class UnionSmallArray {
 public:
  UnionSmallArray()
      : ordinal_(::test_arrays::wire::UnionSmallArray::Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kA = 1,  // 0x1
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_arrays::wire::UnionSmallArray::Ordinal::Invalid;
  }

  bool is_a() const {
    return ordinal_ == ::test_arrays::wire::UnionSmallArray::Ordinal::kA;
  }

  static UnionSmallArray WithA(
      ::fidl::ObjectView<::fidl::Array<uint32_t, 2>> val) {
    UnionSmallArray result;
    result.ordinal_ = ::test_arrays::wire::UnionSmallArray::Ordinal::kA;
    result.envelope_.As<::fidl::Array<uint32_t, 2>>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static UnionSmallArray WithA(::fidl::AnyArena& allocator, Args&&... args) {
    return WithA(::fidl::ObjectView<::fidl::Array<uint32_t, 2>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::Array<uint32_t, 2>& a() {
    ZX_ASSERT(ordinal_ == ::test_arrays::wire::UnionSmallArray::Ordinal::kA);
    return envelope_.As<::fidl::Array<uint32_t, 2>>().get_data();
  }
  const ::fidl::Array<uint32_t, 2>& a() const {
    ZX_ASSERT(ordinal_ == ::test_arrays::wire::UnionSmallArray::Ordinal::kA);
    return envelope_.As<::fidl::Array<uint32_t, 2>>().get_data();
  }
  ::test_arrays::wire::UnionSmallArray::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_arrays::wire::UnionSmallArray::Tag>(ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_arrays::wire::UnionSmallArray::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_arrays_UnionLargeArrayTable;

class UnionLargeArray {
 public:
  UnionLargeArray()
      : ordinal_(::test_arrays::wire::UnionLargeArray::Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kA = 1,  // 0x1
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::test_arrays::wire::UnionLargeArray::Ordinal::Invalid;
  }

  bool is_a() const {
    return ordinal_ == ::test_arrays::wire::UnionLargeArray::Ordinal::kA;
  }

  static UnionLargeArray WithA(
      ::fidl::ObjectView<::fidl::Array<uint32_t, 100>> val) {
    UnionLargeArray result;
    result.ordinal_ = ::test_arrays::wire::UnionLargeArray::Ordinal::kA;
    result.envelope_.As<::fidl::Array<uint32_t, 100>>().set_data(
        std::move(val));
    return result;
  }

  template <typename... Args>
  static UnionLargeArray WithA(::fidl::AnyArena& allocator, Args&&... args) {
    return WithA(::fidl::ObjectView<::fidl::Array<uint32_t, 100>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::Array<uint32_t, 100>& a() {
    ZX_ASSERT(ordinal_ == ::test_arrays::wire::UnionLargeArray::Ordinal::kA);
    return envelope_.As<::fidl::Array<uint32_t, 100>>().get_data();
  }
  const ::fidl::Array<uint32_t, 100>& a() const {
    ZX_ASSERT(ordinal_ == ::test_arrays::wire::UnionLargeArray::Ordinal::kA);
    return envelope_.As<::fidl::Array<uint32_t, 100>>().get_data();
  }
  ::test_arrays::wire::UnionLargeArray::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_arrays::wire::UnionLargeArray::Tag>(ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_arrays::wire::UnionLargeArray::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_arrays_StructSmallArrayTable;

struct StructSmallArray {
  ::fidl::Array<uint32_t, 2> a = {};
};

extern "C" const fidl_type_t test_arrays_StructLargeArrayTable;

struct StructLargeArray {
  ::fidl::Array<uint32_t, 100> a = {};
};

}  // namespace wire
}  // namespace test_arrays
namespace fidl {

template <>
struct TypeTraits<::test_arrays::wire::StructSmallArray> {
  static constexpr const fidl_type_t* kType =
      &::test_arrays::wire::test_arrays_StructSmallArrayTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kPrimarySizeV1 = 8;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasPointer = false;
};

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

template <>
struct TypeTraits<::test_arrays::wire::StructLargeArray> {
  static constexpr const fidl_type_t* kType =
      &::test_arrays::wire::test_arrays_StructLargeArrayTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 400;
  static constexpr uint32_t kPrimarySizeV1 = 400;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasPointer = false;
};

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

template <>
struct TypeTraits<::test_arrays::wire::TableSmallArray> {
  static constexpr const fidl_type_t* kType =
      &::test_arrays::wire::test_arrays_TableSmallArrayTable;
  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 = 16;
  static constexpr uint32_t kMaxOutOfLineV1 = 24;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_arrays::wire::TableSmallArray>
    : public std::true_type {};
template <>
struct IsTable<::test_arrays::wire::TableSmallArray> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_arrays::wire::TableSmallArray>);

template <>
struct TypeTraits<::test_arrays::wire::TableLargeArray> {
  static constexpr const fidl_type_t* kType =
      &::test_arrays::wire::test_arrays_TableLargeArrayTable;
  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 = 408;
  static constexpr uint32_t kMaxOutOfLineV1 = 416;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_arrays::wire::TableLargeArray>
    : public std::true_type {};
template <>
struct IsTable<::test_arrays::wire::TableLargeArray> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_arrays::wire::TableLargeArray>);

template <>
struct TypeTraits<::test_arrays::wire::UnionSmallArray> {
  static constexpr const fidl_type_t* kType =
      &::test_arrays::wire::test_arrays_UnionSmallArrayTable;
  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 = 8;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_arrays::wire::UnionSmallArray>
    : public std::true_type {};
template <>
struct IsUnion<::test_arrays::wire::UnionSmallArray> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_arrays::wire::UnionSmallArray>);

template <>
struct TypeTraits<::test_arrays::wire::UnionLargeArray> {
  static constexpr const fidl_type_t* kType =
      &::test_arrays::wire::test_arrays_UnionLargeArrayTable;
  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 = 400;
  static constexpr uint32_t kMaxOutOfLineV1 = 400;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_arrays::wire::UnionLargeArray>
    : public std::true_type {};
template <>
struct IsUnion<::test_arrays::wire::UnionLargeArray> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_arrays::wire::UnionLargeArray>);

}  // namespace fidl
