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

#pragma once

#include <lib/fidl/internal.h>
#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/buffer_allocator.h>
#include <lib/fidl/llcpp/buffer_then_heap_allocator.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.h>
#include <lib/fidl/llcpp/memory.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/tracking_ptr.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/fit/function.h>
#include <lib/fit/optional.h>

#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/fidl/txn_header.h>
#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace llcpp {

namespace fidl {
namespace test {
namespace arrays {

class UnionSmallArray;
class UnionLargeArray;
class TableSmallArray;
class TableLargeArray;
struct StructSmallArray;
struct StructLargeArray;

extern "C" const fidl_type_t fidl_test_arrays_UnionSmallArrayTable;

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

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

  ~UnionSmallArray() { reset_ptr(nullptr); }

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

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

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

  static UnionSmallArray WithA(
      ::fidl::tracking_ptr<::fidl::Array<uint32_t, 2>>&& val) {
    UnionSmallArray result;
    result.set_a(std::move(val));
    return result;
  }

  void set_a(::fidl::tracking_ptr<::fidl::Array<uint32_t, 2>>&& elem) {
    ordinal_ = Ordinal::kA;
    reset_ptr(static_cast<::fidl::tracking_ptr<void>>(std::move(elem)));
  }

  ::fidl::Array<uint32_t, 2>& mutable_a() {
    ZX_ASSERT(ordinal_ == Ordinal::kA);
    return *static_cast<::fidl::Array<uint32_t, 2>*>(envelope_.data.get());
  }
  const ::fidl::Array<uint32_t, 2>& a() const {
    ZX_ASSERT(ordinal_ == Ordinal::kA);
    return *static_cast<::fidl::Array<uint32_t, 2>*>(envelope_.data.get());
  }
  Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_arrays_UnionSmallArrayTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  void reset_ptr(::fidl::tracking_ptr<void>&& new_ptr) {
    // To clear the existing value, std::move it and let it go out of scope.
    switch (static_cast<fidl_xunion_tag_t>(ordinal_)) {
      case 1: {
        ::fidl::tracking_ptr<::fidl::Array<uint32_t, 2>> to_destroy =
            static_cast<::fidl::tracking_ptr<::fidl::Array<uint32_t, 2>>>(
                std::move(envelope_.data));
        break;
      }
    }

    envelope_.data = std::move(new_ptr);
  }

  static void SizeAndOffsetAssertionHelper();
  Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_arrays_UnionLargeArrayTable;

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

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

  ~UnionLargeArray() { reset_ptr(nullptr); }

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

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

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

  static UnionLargeArray WithA(
      ::fidl::tracking_ptr<::fidl::Array<uint32_t, 100>>&& val) {
    UnionLargeArray result;
    result.set_a(std::move(val));
    return result;
  }

  void set_a(::fidl::tracking_ptr<::fidl::Array<uint32_t, 100>>&& elem) {
    ordinal_ = Ordinal::kA;
    reset_ptr(static_cast<::fidl::tracking_ptr<void>>(std::move(elem)));
  }

  ::fidl::Array<uint32_t, 100>& mutable_a() {
    ZX_ASSERT(ordinal_ == Ordinal::kA);
    return *static_cast<::fidl::Array<uint32_t, 100>*>(envelope_.data.get());
  }
  const ::fidl::Array<uint32_t, 100>& a() const {
    ZX_ASSERT(ordinal_ == Ordinal::kA);
    return *static_cast<::fidl::Array<uint32_t, 100>*>(envelope_.data.get());
  }
  Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_arrays_UnionLargeArrayTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 400;
  static constexpr bool HasPointer = true;

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

  void reset_ptr(::fidl::tracking_ptr<void>&& new_ptr) {
    // To clear the existing value, std::move it and let it go out of scope.
    switch (static_cast<fidl_xunion_tag_t>(ordinal_)) {
      case 1: {
        ::fidl::tracking_ptr<::fidl::Array<uint32_t, 100>> to_destroy =
            static_cast<::fidl::tracking_ptr<::fidl::Array<uint32_t, 100>>>(
                std::move(envelope_.data));
        break;
      }
    }

    envelope_.data = std::move(new_ptr);
  }

  static void SizeAndOffsetAssertionHelper();
  Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_arrays_TableSmallArrayTable;

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

  const ::fidl::Array<uint32_t, 2>& a() const {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  ::fidl::Array<uint32_t, 2>& a() {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  bool has_a() const {
    return max_ordinal_ >= 1 && frame_ptr_->a_.data != nullptr;
  }

  TableSmallArray() = default;
  ~TableSmallArray() = default;
  TableSmallArray(TableSmallArray&& other) noexcept = default;
  TableSmallArray& operator=(TableSmallArray&& other) noexcept = default;

  static constexpr const fidl_type_t* Type =
      &fidl_test_arrays_TableSmallArrayTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 24;
  static constexpr bool HasPointer = true;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          TableSmallArray* value)
        : message_(bytes, byte_size, sizeof(TableSmallArray), nullptr, 0, 0) {
      message_.LinearizeAndEncode<TableSmallArray>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(TableSmallArray* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<TableSmallArray>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<TableSmallArray>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    TableSmallArray* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<TableSmallArray*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<TableSmallArray>();
      }
    }
  };

  class Builder;
  class UnownedBuilder;

  class Frame final {
   public:
    Frame() = default;
    // In its intended usage, Frame will be referenced by a tracking_ptr. If the
    // tracking_ptr 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.
    Frame(const Frame&) = delete;
    Frame& operator=(const Frame&) = delete;

   private:
    Frame(Frame&&) noexcept = default;
    Frame& operator=(Frame&&) noexcept = default;
    ::fidl::Envelope<::fidl::Array<uint32_t, 2>> a_;

    friend class TableSmallArray;
    friend class TableSmallArray::Builder;
    friend class TableSmallArray::UnownedBuilder;
  };

 private:
  TableSmallArray(uint64_t max_ordinal, ::fidl::tracking_ptr<Frame>&& frame_ptr)
      : max_ordinal_(max_ordinal), frame_ptr_(std::move(frame_ptr)) {}
  uint64_t max_ordinal_ = 0;
  ::fidl::tracking_ptr<Frame> frame_ptr_;
};

// TableSmallArray::Builder builds TableSmallArray.
// Usage:
// TableSmallArray val =
// TableSmallArray::Builder(std::make_unique<TableSmallArray::Frame>())
// .set_a(ptr)
// .build();
class TableSmallArray::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<TableSmallArray::Frame>&& frame_ptr)
      : max_ordinal_(0), frame_ptr_(std::move(frame_ptr)) {}

  Builder(Builder&& other) noexcept = default;
  Builder& operator=(Builder&& other) noexcept = default;

  Builder(const Builder& other) = delete;
  Builder& operator=(const Builder& other) = delete;

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

  Builder&& set_a(::fidl::tracking_ptr<::fidl::Array<uint32_t, 2>> elem) {
    frame_ptr_->a_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const ::fidl::Array<uint32_t, 2>& a() const {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  ::fidl::Array<uint32_t, 2>& a() {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  bool has_a() const {
    return max_ordinal_ >= 1 && frame_ptr_->a_.data != nullptr;
  }

  TableSmallArray build() {
    return TableSmallArray(max_ordinal_, std::move(frame_ptr_));
  }

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::tracking_ptr<TableSmallArray::Frame> frame_ptr_;
};

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class TableSmallArray::UnownedBuilder final {
 public:
  ~UnownedBuilder() = default;
  UnownedBuilder() noexcept = default;
  UnownedBuilder(UnownedBuilder&& other) noexcept = default;
  UnownedBuilder& operator=(UnownedBuilder&& other) noexcept = default;

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

  UnownedBuilder&& set_a(
      ::fidl::tracking_ptr<::fidl::Array<uint32_t, 2>> elem) {
    ZX_ASSERT(elem);
    frame_.a_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const ::fidl::Array<uint32_t, 2>& a() const {
    ZX_ASSERT(has_a());
    return *frame_.a_.data;
  }
  ::fidl::Array<uint32_t, 2>& a() {
    ZX_ASSERT(has_a());
    return *frame_.a_.data;
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_.a_.data != nullptr; }

  TableSmallArray build() {
    return TableSmallArray(max_ordinal_, ::fidl::unowned_ptr(&frame_));
  }

 private:
  uint64_t max_ordinal_ = 0;
  TableSmallArray::Frame frame_;
};

extern "C" const fidl_type_t fidl_test_arrays_TableLargeArrayTable;

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

  const ::fidl::Array<uint32_t, 100>& a() const {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  ::fidl::Array<uint32_t, 100>& a() {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  bool has_a() const {
    return max_ordinal_ >= 1 && frame_ptr_->a_.data != nullptr;
  }

  TableLargeArray() = default;
  ~TableLargeArray() = default;
  TableLargeArray(TableLargeArray&& other) noexcept = default;
  TableLargeArray& operator=(TableLargeArray&& other) noexcept = default;

  static constexpr const fidl_type_t* Type =
      &fidl_test_arrays_TableLargeArrayTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 416;
  static constexpr bool HasPointer = true;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          TableLargeArray* value)
        : message_(bytes, byte_size, sizeof(TableLargeArray), nullptr, 0, 0) {
      message_.LinearizeAndEncode<TableLargeArray>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(TableLargeArray* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<TableLargeArray>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<TableLargeArray>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    TableLargeArray* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<TableLargeArray*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<TableLargeArray>();
      }
    }
  };

  class Builder;
  class UnownedBuilder;

  class Frame final {
   public:
    Frame() = default;
    // In its intended usage, Frame will be referenced by a tracking_ptr. If the
    // tracking_ptr 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.
    Frame(const Frame&) = delete;
    Frame& operator=(const Frame&) = delete;

   private:
    Frame(Frame&&) noexcept = default;
    Frame& operator=(Frame&&) noexcept = default;
    ::fidl::Envelope<::fidl::Array<uint32_t, 100>> a_;

    friend class TableLargeArray;
    friend class TableLargeArray::Builder;
    friend class TableLargeArray::UnownedBuilder;
  };

 private:
  TableLargeArray(uint64_t max_ordinal, ::fidl::tracking_ptr<Frame>&& frame_ptr)
      : max_ordinal_(max_ordinal), frame_ptr_(std::move(frame_ptr)) {}
  uint64_t max_ordinal_ = 0;
  ::fidl::tracking_ptr<Frame> frame_ptr_;
};

// TableLargeArray::Builder builds TableLargeArray.
// Usage:
// TableLargeArray val =
// TableLargeArray::Builder(std::make_unique<TableLargeArray::Frame>())
// .set_a(ptr)
// .build();
class TableLargeArray::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<TableLargeArray::Frame>&& frame_ptr)
      : max_ordinal_(0), frame_ptr_(std::move(frame_ptr)) {}

  Builder(Builder&& other) noexcept = default;
  Builder& operator=(Builder&& other) noexcept = default;

  Builder(const Builder& other) = delete;
  Builder& operator=(const Builder& other) = delete;

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

  Builder&& set_a(::fidl::tracking_ptr<::fidl::Array<uint32_t, 100>> elem) {
    frame_ptr_->a_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const ::fidl::Array<uint32_t, 100>& a() const {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  ::fidl::Array<uint32_t, 100>& a() {
    ZX_ASSERT(has_a());
    return *frame_ptr_->a_.data;
  }
  bool has_a() const {
    return max_ordinal_ >= 1 && frame_ptr_->a_.data != nullptr;
  }

  TableLargeArray build() {
    return TableLargeArray(max_ordinal_, std::move(frame_ptr_));
  }

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::tracking_ptr<TableLargeArray::Frame> frame_ptr_;
};

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class TableLargeArray::UnownedBuilder final {
 public:
  ~UnownedBuilder() = default;
  UnownedBuilder() noexcept = default;
  UnownedBuilder(UnownedBuilder&& other) noexcept = default;
  UnownedBuilder& operator=(UnownedBuilder&& other) noexcept = default;

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

  UnownedBuilder&& set_a(
      ::fidl::tracking_ptr<::fidl::Array<uint32_t, 100>> elem) {
    ZX_ASSERT(elem);
    frame_.a_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const ::fidl::Array<uint32_t, 100>& a() const {
    ZX_ASSERT(has_a());
    return *frame_.a_.data;
  }
  ::fidl::Array<uint32_t, 100>& a() {
    ZX_ASSERT(has_a());
    return *frame_.a_.data;
  }
  bool has_a() const { return max_ordinal_ >= 1 && frame_.a_.data != nullptr; }

  TableLargeArray build() {
    return TableLargeArray(max_ordinal_, ::fidl::unowned_ptr(&frame_));
  }

 private:
  uint64_t max_ordinal_ = 0;
  TableLargeArray::Frame frame_;
};

extern "C" const fidl_type_t fidl_test_arrays_StructSmallArrayTable;

struct StructSmallArray {
  static constexpr const fidl_type_t* Type =
      &fidl_test_arrays_StructSmallArrayTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 8;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

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

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          StructSmallArray* value)
        : message_(bytes, byte_size, sizeof(StructSmallArray), nullptr, 0, 0) {
      message_.LinearizeAndEncode<StructSmallArray>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(StructSmallArray* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct StructSmallArray>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct StructSmallArray>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct StructSmallArray* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct StructSmallArray*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct StructSmallArray>();
      }
    }
  };
};

extern "C" const fidl_type_t fidl_test_arrays_StructLargeArrayTable;

struct StructLargeArray {
  static constexpr const fidl_type_t* Type =
      &fidl_test_arrays_StructLargeArrayTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 400;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

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

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          StructLargeArray* value)
        : message_(bytes, byte_size, sizeof(StructLargeArray), nullptr, 0, 0) {
      message_.LinearizeAndEncode<StructLargeArray>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(StructLargeArray* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct StructLargeArray>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct StructLargeArray>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct StructLargeArray* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct StructLargeArray*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct StructLargeArray>();
      }
    }
  };
};

}  // namespace arrays
}  // namespace test
}  // namespace fidl
}  // namespace llcpp

namespace fidl {

template <>
struct IsFidlType<::llcpp::fidl::test::arrays::UnionSmallArray>
    : public std::true_type {};
template <>
struct IsUnion<::llcpp::fidl::test::arrays::UnionSmallArray>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::arrays::UnionSmallArray>);

template <>
struct IsFidlType<::llcpp::fidl::test::arrays::UnionLargeArray>
    : public std::true_type {};
template <>
struct IsUnion<::llcpp::fidl::test::arrays::UnionLargeArray>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::arrays::UnionLargeArray>);

template <>
struct IsFidlType<::llcpp::fidl::test::arrays::TableSmallArray>
    : public std::true_type {};
template <>
struct IsTable<::llcpp::fidl::test::arrays::TableSmallArray>
    : public std::true_type {};
template <>
struct IsTableBuilder<::llcpp::fidl::test::arrays::TableSmallArray::Builder>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::arrays::TableSmallArray>);

template <>
struct IsFidlType<::llcpp::fidl::test::arrays::TableLargeArray>
    : public std::true_type {};
template <>
struct IsTable<::llcpp::fidl::test::arrays::TableLargeArray>
    : public std::true_type {};
template <>
struct IsTableBuilder<::llcpp::fidl::test::arrays::TableLargeArray::Builder>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::arrays::TableLargeArray>);

template <>
struct IsFidlType<::llcpp::fidl::test::arrays::StructSmallArray>
    : public std::true_type {};
template <>
struct IsStruct<::llcpp::fidl::test::arrays::StructSmallArray>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::arrays::StructSmallArray>);
static_assert(offsetof(::llcpp::fidl::test::arrays::StructSmallArray, a) == 0);
static_assert(sizeof(::llcpp::fidl::test::arrays::StructSmallArray) ==
              ::llcpp::fidl::test::arrays::StructSmallArray::PrimarySize);

template <>
struct IsFidlType<::llcpp::fidl::test::arrays::StructLargeArray>
    : public std::true_type {};
template <>
struct IsStruct<::llcpp::fidl::test::arrays::StructLargeArray>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::arrays::StructLargeArray>);
static_assert(offsetof(::llcpp::fidl::test::arrays::StructLargeArray, a) == 0);
static_assert(sizeof(::llcpp::fidl::test::arrays::StructLargeArray) ==
              ::llcpp::fidl::test::arrays::StructLargeArray::PrimarySize);

}  // namespace fidl

namespace llcpp {

namespace fidl {
namespace test {
namespace arrays {}  // namespace arrays
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
