// 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/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.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/vector_view.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>

#include <algorithm>
#include <cstddef>
#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.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/llcpp/wire_messaging.h>
#include <lib/fidl/txn_header.h>

#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace fidl_test_table {
namespace wire {
class SimpleTable;

class ReverseOrdinalTable;

class OlderSimpleTable;

class NewerSimpleTable;

class EmptyTable;

extern "C" const fidl_type_t fidl_test_table_SimpleTableTable;

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

  class Frame_;

  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  bool has_x() const {
    return max_ordinal_ >= 1 && frame_ptr_->x_.data != nullptr;
  }
  SimpleTable& set_x(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  SimpleTable& set_x(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  SimpleTable& set_x(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  const int64_t& y() const {
    ZX_ASSERT(has_y());
    return *frame_ptr_->y_.data;
  }
  int64_t& y() {
    ZX_ASSERT(has_y());
    return *frame_ptr_->y_.data;
  }
  bool has_y() const {
    return max_ordinal_ >= 5 && frame_ptr_->y_.data != nullptr;
  }
  SimpleTable& set_y(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(5));
    return *this;
  }
  SimpleTable& set_y(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  SimpleTable& set_y(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(5));
    return *this;
  }

  SimpleTable() = default;
  explicit SimpleTable(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame_>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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 SimpleTable(::fidl::ObjectView<Frame_>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~SimpleTable() = default;
  SimpleTable(const SimpleTable& other) noexcept = default;
  SimpleTable& operator=(const SimpleTable& other) noexcept = default;
  SimpleTable(SimpleTable&& other) noexcept = default;
  SimpleTable& operator=(SimpleTable&& other) noexcept = default;

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

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame_>(allocator);
  }
  void Init(::fidl::ObjectView<Frame_>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          SimpleTable* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(SimpleTable)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<SimpleTable>(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  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(SimpleTable* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), 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  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<112> backing_buffer_;
    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<SimpleTable>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<SimpleTable>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    SimpleTable* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<SimpleTable*>(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(); }
  };

  // Frame_s are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame_ final {
   public:
    Frame_() = default;
    // In its intended usage, Frame_ 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.
    Frame_(const Frame_&) = delete;
    Frame_& operator=(const Frame_&) = delete;

   private:
    Frame_(Frame_&&) noexcept = default;
    Frame_& operator=(Frame_&&) noexcept = default;
    ::fidl::Envelope<int64_t> x_;
    ::fidl::Envelope<void> reserved_1_;
    ::fidl::Envelope<void> reserved_2_;
    ::fidl::Envelope<void> reserved_3_;
    ::fidl::Envelope<int64_t> y_;

    friend class SimpleTable;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame_> frame_ptr_;
};

extern "C" const fidl_type_t fidl_test_table_ReverseOrdinalTableTable;

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

  class Frame_;

  const int64_t& z() const {
    ZX_ASSERT(has_z());
    return *frame_ptr_->z_.data;
  }
  int64_t& z() {
    ZX_ASSERT(has_z());
    return *frame_ptr_->z_.data;
  }
  bool has_z() const {
    return max_ordinal_ >= 1 && frame_ptr_->z_.data != nullptr;
  }
  ReverseOrdinalTable& set_z(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->z_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  ReverseOrdinalTable& set_z(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->z_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  ReverseOrdinalTable& set_z(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->z_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  const int64_t& y() const {
    ZX_ASSERT(has_y());
    return *frame_ptr_->y_.data;
  }
  int64_t& y() {
    ZX_ASSERT(has_y());
    return *frame_ptr_->y_.data;
  }
  bool has_y() const {
    return max_ordinal_ >= 2 && frame_ptr_->y_.data != nullptr;
  }
  ReverseOrdinalTable& set_y(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(2));
    return *this;
  }
  ReverseOrdinalTable& set_y(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  ReverseOrdinalTable& set_y(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(2));
    return *this;
  }

  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  bool has_x() const {
    return max_ordinal_ >= 3 && frame_ptr_->x_.data != nullptr;
  }
  ReverseOrdinalTable& set_x(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(3));
    return *this;
  }
  ReverseOrdinalTable& set_x(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  ReverseOrdinalTable& set_x(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(3));
    return *this;
  }

  ReverseOrdinalTable() = default;
  explicit ReverseOrdinalTable(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame_>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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 ReverseOrdinalTable(::fidl::ObjectView<Frame_>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~ReverseOrdinalTable() = default;
  ReverseOrdinalTable(const ReverseOrdinalTable& other) noexcept = default;
  ReverseOrdinalTable& operator=(const ReverseOrdinalTable& other) noexcept =
      default;
  ReverseOrdinalTable(ReverseOrdinalTable&& other) noexcept = default;
  ReverseOrdinalTable& operator=(ReverseOrdinalTable&& other) noexcept =
      default;

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

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame_>(allocator);
  }
  void Init(::fidl::ObjectView<Frame_>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          ReverseOrdinalTable* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(ReverseOrdinalTable)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<ReverseOrdinalTable>(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  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(ReverseOrdinalTable* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), 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  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<88> backing_buffer_;
    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<ReverseOrdinalTable>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<ReverseOrdinalTable>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    ReverseOrdinalTable* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<ReverseOrdinalTable*>(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(); }
  };

  // Frame_s are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame_ final {
   public:
    Frame_() = default;
    // In its intended usage, Frame_ 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.
    Frame_(const Frame_&) = delete;
    Frame_& operator=(const Frame_&) = delete;

   private:
    Frame_(Frame_&&) noexcept = default;
    Frame_& operator=(Frame_&&) noexcept = default;
    ::fidl::Envelope<int64_t> z_;
    ::fidl::Envelope<int64_t> y_;
    ::fidl::Envelope<int64_t> x_;

    friend class ReverseOrdinalTable;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame_> frame_ptr_;
};

extern "C" const fidl_type_t fidl_test_table_OlderSimpleTableTable;

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

  class Frame_;

  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  bool has_x() const {
    return max_ordinal_ >= 1 && frame_ptr_->x_.data != nullptr;
  }
  OlderSimpleTable& set_x(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  OlderSimpleTable& set_x(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  OlderSimpleTable& set_x(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  OlderSimpleTable() = default;
  explicit OlderSimpleTable(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame_>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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 OlderSimpleTable(::fidl::ObjectView<Frame_>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~OlderSimpleTable() = default;
  OlderSimpleTable(const OlderSimpleTable& other) noexcept = default;
  OlderSimpleTable& operator=(const OlderSimpleTable& other) noexcept = default;
  OlderSimpleTable(OlderSimpleTable&& other) noexcept = default;
  OlderSimpleTable& operator=(OlderSimpleTable&& other) noexcept = default;

  static constexpr const fidl_type_t* Type =
      &fidl_test_table_OlderSimpleTableTable;
  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;

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame_>(allocator);
  }
  void Init(::fidl::ObjectView<Frame_>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          OlderSimpleTable* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(OlderSimpleTable)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<OlderSimpleTable>(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  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(OlderSimpleTable* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), 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  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<40> backing_buffer_;
    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<OlderSimpleTable>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<OlderSimpleTable>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    OlderSimpleTable* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<OlderSimpleTable*>(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(); }
  };

  // Frame_s are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame_ final {
   public:
    Frame_() = default;
    // In its intended usage, Frame_ 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.
    Frame_(const Frame_&) = delete;
    Frame_& operator=(const Frame_&) = delete;

   private:
    Frame_(Frame_&&) noexcept = default;
    Frame_& operator=(Frame_&&) noexcept = default;
    ::fidl::Envelope<int64_t> x_;

    friend class OlderSimpleTable;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame_> frame_ptr_;
};

extern "C" const fidl_type_t fidl_test_table_NewerSimpleTableTable;

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

  class Frame_;

  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_ptr_->x_.data;
  }
  bool has_x() const {
    return max_ordinal_ >= 1 && frame_ptr_->x_.data != nullptr;
  }
  NewerSimpleTable& set_x(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  NewerSimpleTable& set_x(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  NewerSimpleTable& set_x(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->x_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  const int64_t& y() const {
    ZX_ASSERT(has_y());
    return *frame_ptr_->y_.data;
  }
  int64_t& y() {
    ZX_ASSERT(has_y());
    return *frame_ptr_->y_.data;
  }
  bool has_y() const {
    return max_ordinal_ >= 5 && frame_ptr_->y_.data != nullptr;
  }
  NewerSimpleTable& set_y(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(5));
    return *this;
  }
  NewerSimpleTable& set_y(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  NewerSimpleTable& set_y(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->y_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(5));
    return *this;
  }

  const int64_t& z() const {
    ZX_ASSERT(has_z());
    return *frame_ptr_->z_.data;
  }
  int64_t& z() {
    ZX_ASSERT(has_z());
    return *frame_ptr_->z_.data;
  }
  bool has_z() const {
    return max_ordinal_ >= 6 && frame_ptr_->z_.data != nullptr;
  }
  NewerSimpleTable& set_z(::fidl::ObjectView<int64_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->z_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(6));
    return *this;
  }
  NewerSimpleTable& set_z(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->z_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  NewerSimpleTable& set_z(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->z_.data =
        ::fidl::ObjectView<int64_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(6));
    return *this;
  }

  NewerSimpleTable() = default;
  explicit NewerSimpleTable(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame_>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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 NewerSimpleTable(::fidl::ObjectView<Frame_>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~NewerSimpleTable() = default;
  NewerSimpleTable(const NewerSimpleTable& other) noexcept = default;
  NewerSimpleTable& operator=(const NewerSimpleTable& other) noexcept = default;
  NewerSimpleTable(NewerSimpleTable&& other) noexcept = default;
  NewerSimpleTable& operator=(NewerSimpleTable&& other) noexcept = default;

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

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame_>(allocator);
  }
  void Init(::fidl::ObjectView<Frame_>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          NewerSimpleTable* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(NewerSimpleTable)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<NewerSimpleTable>(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  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(NewerSimpleTable* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), 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  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<136> backing_buffer_;
    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<NewerSimpleTable>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<NewerSimpleTable>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    NewerSimpleTable* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<NewerSimpleTable*>(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(); }
  };

  // Frame_s are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame_ final {
   public:
    Frame_() = default;
    // In its intended usage, Frame_ 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.
    Frame_(const Frame_&) = delete;
    Frame_& operator=(const Frame_&) = delete;

   private:
    Frame_(Frame_&&) noexcept = default;
    Frame_& operator=(Frame_&&) noexcept = default;
    ::fidl::Envelope<int64_t> x_;
    ::fidl::Envelope<void> reserved_1_;
    ::fidl::Envelope<void> reserved_2_;
    ::fidl::Envelope<void> reserved_3_;
    ::fidl::Envelope<int64_t> y_;
    ::fidl::Envelope<int64_t> z_;

    friend class NewerSimpleTable;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame_> frame_ptr_;
};

extern "C" const fidl_type_t fidl_test_table_EmptyTableTable;

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

  class Frame_;

  EmptyTable() = default;
  explicit EmptyTable(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame_>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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 EmptyTable(::fidl::ObjectView<Frame_>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~EmptyTable() = default;
  EmptyTable(const EmptyTable& other) noexcept = default;
  EmptyTable& operator=(const EmptyTable& other) noexcept = default;
  EmptyTable(EmptyTable&& other) noexcept = default;
  EmptyTable& operator=(EmptyTable&& other) noexcept = default;

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

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame_>(allocator);
  }
  void Init(::fidl::ObjectView<Frame_>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          EmptyTable* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(EmptyTable)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<EmptyTable>(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  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(EmptyTable* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), 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  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<16> backing_buffer_;
    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<EmptyTable>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<EmptyTable>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    EmptyTable* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<EmptyTable*>(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(); }
  };

  // Frame_s are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame_ final {
   public:
    Frame_() = default;
    // In its intended usage, Frame_ 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.
    Frame_(const Frame_&) = delete;
    Frame_& operator=(const Frame_&) = delete;

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

    friend class EmptyTable;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame_> frame_ptr_;
};

}  // namespace wire
}  // namespace fidl_test_table
namespace fidl {

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

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

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

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

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

}  // namespace fidl
