// 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 table {

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; }

  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;
  }

  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() = default;
  ~SimpleTable() = 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;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          SimpleTable* value)
        : message_(bytes, byte_size, sizeof(SimpleTable), nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(SimpleTable* 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<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(); }

    // 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<SimpleTable>();
      }
    }
  };

  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<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;
    friend class SimpleTable::Builder;
    friend class SimpleTable::UnownedBuilder;
  };

 private:
  SimpleTable(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_;
};

// SimpleTable::Builder builds SimpleTable.
// Usage:
// SimpleTable val =
// SimpleTable::Builder(std::make_unique<SimpleTable::Frame>()) .set_x(ptr)
// .build();
class SimpleTable::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<SimpleTable::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_x(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->x_.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 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;
  }

  Builder&& set_y(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->y_.data = std::move(elem);
    if (max_ordinal_ < 5) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 5;
    }
    return std::move(*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 build() {
    return SimpleTable(max_ordinal_, std::move(frame_ptr_));
  }

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

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class SimpleTable::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_x(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.x_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  bool has_x() const { return max_ordinal_ >= 1 && frame_.x_.data != nullptr; }

  UnownedBuilder&& set_y(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.y_.data = std::move(elem);
    if (max_ordinal_ < 5) {
      max_ordinal_ = 5;
    }
    return std::move(*this);
  }
  const int64_t& y() const {
    ZX_ASSERT(has_y());
    return *frame_.y_.data;
  }
  int64_t& y() {
    ZX_ASSERT(has_y());
    return *frame_.y_.data;
  }
  bool has_y() const { return max_ordinal_ >= 5 && frame_.y_.data != nullptr; }

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

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

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; }

  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;
  }

  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;
  }

  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() = default;
  ~ReverseOrdinalTable() = 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;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          ReverseOrdinalTable* value)
        : message_(bytes, byte_size, sizeof(ReverseOrdinalTable), nullptr, 0,
                   0) {
      message_.LinearizeAndEncode<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
    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(ReverseOrdinalTable* 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<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(); }

    // 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<ReverseOrdinalTable>();
      }
    }
  };

  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<int64_t> z_;
    ::fidl::Envelope<int64_t> y_;
    ::fidl::Envelope<int64_t> x_;

    friend class ReverseOrdinalTable;
    friend class ReverseOrdinalTable::Builder;
    friend class ReverseOrdinalTable::UnownedBuilder;
  };

 private:
  ReverseOrdinalTable(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_;
};

// ReverseOrdinalTable::Builder builds ReverseOrdinalTable.
// Usage:
// ReverseOrdinalTable val =
// ReverseOrdinalTable::Builder(std::make_unique<ReverseOrdinalTable::Frame>())
// .set_z(ptr)
// .build();
class ReverseOrdinalTable::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<ReverseOrdinalTable::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_z(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->z_.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 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;
  }

  Builder&& set_y(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->y_.data = std::move(elem);
    if (max_ordinal_ < 2) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 2;
    }
    return std::move(*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;
  }

  Builder&& set_x(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->x_.data = std::move(elem);
    if (max_ordinal_ < 3) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 3;
    }
    return std::move(*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 build() {
    return ReverseOrdinalTable(max_ordinal_, std::move(frame_ptr_));
  }

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

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class ReverseOrdinalTable::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_z(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.z_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const int64_t& z() const {
    ZX_ASSERT(has_z());
    return *frame_.z_.data;
  }
  int64_t& z() {
    ZX_ASSERT(has_z());
    return *frame_.z_.data;
  }
  bool has_z() const { return max_ordinal_ >= 1 && frame_.z_.data != nullptr; }

  UnownedBuilder&& set_y(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.y_.data = std::move(elem);
    if (max_ordinal_ < 2) {
      max_ordinal_ = 2;
    }
    return std::move(*this);
  }
  const int64_t& y() const {
    ZX_ASSERT(has_y());
    return *frame_.y_.data;
  }
  int64_t& y() {
    ZX_ASSERT(has_y());
    return *frame_.y_.data;
  }
  bool has_y() const { return max_ordinal_ >= 2 && frame_.y_.data != nullptr; }

  UnownedBuilder&& set_x(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.x_.data = std::move(elem);
    if (max_ordinal_ < 3) {
      max_ordinal_ = 3;
    }
    return std::move(*this);
  }
  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  bool has_x() const { return max_ordinal_ >= 3 && frame_.x_.data != nullptr; }

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

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

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; }

  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() = default;
  ~OlderSimpleTable() = 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;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          OlderSimpleTable* value)
        : message_(bytes, byte_size, sizeof(OlderSimpleTable), nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(OlderSimpleTable* 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<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(); }

    // 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<OlderSimpleTable>();
      }
    }
  };

  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<int64_t> x_;

    friend class OlderSimpleTable;
    friend class OlderSimpleTable::Builder;
    friend class OlderSimpleTable::UnownedBuilder;
  };

 private:
  OlderSimpleTable(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_;
};

// OlderSimpleTable::Builder builds OlderSimpleTable.
// Usage:
// OlderSimpleTable val =
// OlderSimpleTable::Builder(std::make_unique<OlderSimpleTable::Frame>())
// .set_x(ptr)
// .build();
class OlderSimpleTable::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<OlderSimpleTable::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_x(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->x_.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 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 build() {
    return OlderSimpleTable(max_ordinal_, std::move(frame_ptr_));
  }

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

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class OlderSimpleTable::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_x(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.x_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  bool has_x() const { return max_ordinal_ >= 1 && frame_.x_.data != nullptr; }

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

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

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; }

  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;
  }

  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;
  }

  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() = default;
  ~NewerSimpleTable() = 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;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          NewerSimpleTable* value)
        : message_(bytes, byte_size, sizeof(NewerSimpleTable), nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(NewerSimpleTable* 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<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(); }

    // 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<NewerSimpleTable>();
      }
    }
  };

  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<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;
    friend class NewerSimpleTable::Builder;
    friend class NewerSimpleTable::UnownedBuilder;
  };

 private:
  NewerSimpleTable(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_;
};

// NewerSimpleTable::Builder builds NewerSimpleTable.
// Usage:
// NewerSimpleTable val =
// NewerSimpleTable::Builder(std::make_unique<NewerSimpleTable::Frame>())
// .set_x(ptr)
// .build();
class NewerSimpleTable::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<NewerSimpleTable::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_x(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->x_.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 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;
  }

  Builder&& set_y(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->y_.data = std::move(elem);
    if (max_ordinal_ < 5) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 5;
    }
    return std::move(*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;
  }

  Builder&& set_z(::fidl::tracking_ptr<int64_t> elem) {
    frame_ptr_->z_.data = std::move(elem);
    if (max_ordinal_ < 6) {
      // Note: the table size is not currently reduced if nullptr is set.
      // This is possible to reconsider in the future.
      max_ordinal_ = 6;
    }
    return std::move(*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 build() {
    return NewerSimpleTable(max_ordinal_, std::move(frame_ptr_));
  }

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

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class NewerSimpleTable::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_x(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.x_.data = std::move(elem);
    if (max_ordinal_ < 1) {
      max_ordinal_ = 1;
    }
    return std::move(*this);
  }
  const int64_t& x() const {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  int64_t& x() {
    ZX_ASSERT(has_x());
    return *frame_.x_.data;
  }
  bool has_x() const { return max_ordinal_ >= 1 && frame_.x_.data != nullptr; }

  UnownedBuilder&& set_y(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.y_.data = std::move(elem);
    if (max_ordinal_ < 5) {
      max_ordinal_ = 5;
    }
    return std::move(*this);
  }
  const int64_t& y() const {
    ZX_ASSERT(has_y());
    return *frame_.y_.data;
  }
  int64_t& y() {
    ZX_ASSERT(has_y());
    return *frame_.y_.data;
  }
  bool has_y() const { return max_ordinal_ >= 5 && frame_.y_.data != nullptr; }

  UnownedBuilder&& set_z(::fidl::tracking_ptr<int64_t> elem) {
    ZX_ASSERT(elem);
    frame_.z_.data = std::move(elem);
    if (max_ordinal_ < 6) {
      max_ordinal_ = 6;
    }
    return std::move(*this);
  }
  const int64_t& z() const {
    ZX_ASSERT(has_z());
    return *frame_.z_.data;
  }
  int64_t& z() {
    ZX_ASSERT(has_z());
    return *frame_.z_.data;
  }
  bool has_z() const { return max_ordinal_ >= 6 && frame_.z_.data != nullptr; }

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

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

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; }

  EmptyTable() = default;
  ~EmptyTable() = 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;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size, EmptyTable* value)
        : message_(bytes, byte_size, sizeof(EmptyTable), nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(EmptyTable* 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<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(); }

    // 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<EmptyTable>();
      }
    }
  };

  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;

    friend class EmptyTable;
    friend class EmptyTable::Builder;
    friend class EmptyTable::UnownedBuilder;
  };

 private:
  EmptyTable(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_;
};

// EmptyTable::Builder builds EmptyTable.
// Usage:
// EmptyTable val = EmptyTable::Builder(std::make_unique<EmptyTable::Frame>())

// .build();
class EmptyTable::Builder final {
 public:
  ~Builder() = default;
  Builder() = delete;
  Builder(::fidl::tracking_ptr<EmptyTable::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; }

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

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

// UnownedBuilder acts like Builder but directly owns its Frame, simplifying
// working with unowned data.
class EmptyTable::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; }

  EmptyTable build() { return EmptyTable(max_ordinal_, nullptr); }

 private:
  uint64_t max_ordinal_ = 0;
};

}  // namespace table
}  // namespace test
}  // namespace fidl
}  // namespace llcpp

namespace fidl {

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

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

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

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

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

}  // namespace fidl

namespace llcpp {

namespace fidl {
namespace test {
namespace table {}  // namespace table
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
