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

#include <fidl/test/table/cpp/natural_types.h>

#include "lib/fidl/cpp/internal/natural_types_implementation.h"

//
// Domain objects definitions (i.e. "natural types" in unified bindings)
//
namespace fidl {
namespace test {
namespace table {
extern "C" const fidl_type_t fidl_test_table_SimpleTableTable;
const fidl_type_t* SimpleTable::FidlType = &fidl_test_table_SimpleTableTable;

SimpleTable::SimpleTable() {}

SimpleTable::SimpleTable(SimpleTable&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&x_value_.value, std::move(other.x_value_.value));
  }
  if (field_presence_.IsSet<4>()) {
    Construct(&y_value_.value, std::move(other.y_value_.value));
  }
  _unknown_data = std::move(other._unknown_data);
}

SimpleTable::~SimpleTable() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&x_value_.value);
  }
  if (field_presence_.IsSet<4>()) {
    Destruct(&y_value_.value);
  }
}

SimpleTable& SimpleTable::operator=(SimpleTable&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      x_value_.value = std::move(other.x_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&x_value_.value, std::move(other.x_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&x_value_.value);
  }
  if (other.field_presence_.IsSet<4>()) {
    if (field_presence_.IsSet<4>()) {
      y_value_.value = std::move(other.y_value_.value);
    } else {
      field_presence_.Set<4>();
      Construct(&y_value_.value, std::move(other.y_value_.value));
    }
  } else if (field_presence_.IsSet<4>()) {
    field_presence_.Clear<4>();
    Destruct(&y_value_.value);
  }
  _unknown_data = std::move(other._unknown_data);
  return *this;
}

bool SimpleTable::IsEmpty() const {
  return field_presence_.IsEmpty() && _unknown_data.size() == 0;
}

void SimpleTable::Encode(
    ::fidl::Encoder* _encoder, size_t _offset,
    cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  auto next_unknown = _unknown_data.begin();
  if (field_presence_.IsSet<0>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 1) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &x_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  if (field_presence_.IsSet<4>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 5) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &y_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (5 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  // Encode any remaining unknown fields (i.e. ones that have an ordinal outside
  // the range of known ordinals)
  for (auto curr = next_unknown; curr != _unknown_data.end(); ++curr) {
    size_t envelope_base = base + (curr->first - 1) * sizeof(fidl_envelope_t);
    ::fidl::EncodeUnknownBytes(_encoder, &curr->second, envelope_base);
  }
}

void SimpleTable::Decode(::fidl::Decoder* _decoder, SimpleTable* _value,
                         size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  size_t base;
  size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_x(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_x();
    }
  } else {
    goto done_1;
  }
  if (count >= 5) {
    size_t envelope_base = base + (5 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_y(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_y();
    }
  } else {
    goto done_5;
  }

  if (count > 2) {
    for (uint64_t ordinal = 1; ordinal <= count; ordinal++) {
      if (IsOrdinalKnown(ordinal)) continue;

      size_t envelope_base = base + (ordinal - 1) * sizeof(fidl_envelope_t);
      fidl_envelope_t* envelope =
          _decoder->GetPtr<fidl_envelope_t>(envelope_base);
      if (envelope->presence != 0) {
        auto result = _value->_unknown_data.emplace(
            std::piecewise_construct, std::forward_as_tuple(ordinal),
            std::forward_as_tuple());
        auto iter = result.first;
        iter->second.resize(envelope->num_bytes);
        ::fidl::DecodeUnknownBytesContents(_decoder, &iter->second,
                                           _decoder->GetOffset(envelope->data));
      }
    }
  }

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_x();
done_5:
  _value->clear_y();
  return;
}

zx_status_t SimpleTable::Clone(SimpleTable* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(x_value_.value, result->mutable_x());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_x();
  }
  if (field_presence_.IsSet<4>()) {
    zx_status_t _status = ::fidl::Clone(y_value_.value, result->mutable_y());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_y();
  }
  return ::fidl::Clone(_unknown_data, &result->_unknown_data);
}

extern "C" const fidl_type_t fidl_test_table_ReverseOrdinalTableTable;
const fidl_type_t* ReverseOrdinalTable::FidlType =
    &fidl_test_table_ReverseOrdinalTableTable;

ReverseOrdinalTable::ReverseOrdinalTable() {}

ReverseOrdinalTable::ReverseOrdinalTable(ReverseOrdinalTable&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&z_value_.value, std::move(other.z_value_.value));
  }
  if (field_presence_.IsSet<1>()) {
    Construct(&y_value_.value, std::move(other.y_value_.value));
  }
  if (field_presence_.IsSet<2>()) {
    Construct(&x_value_.value, std::move(other.x_value_.value));
  }
  _unknown_data = std::move(other._unknown_data);
}

ReverseOrdinalTable::~ReverseOrdinalTable() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&z_value_.value);
  }
  if (field_presence_.IsSet<1>()) {
    Destruct(&y_value_.value);
  }
  if (field_presence_.IsSet<2>()) {
    Destruct(&x_value_.value);
  }
}

ReverseOrdinalTable& ReverseOrdinalTable::operator=(
    ReverseOrdinalTable&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      z_value_.value = std::move(other.z_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&z_value_.value, std::move(other.z_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&z_value_.value);
  }
  if (other.field_presence_.IsSet<1>()) {
    if (field_presence_.IsSet<1>()) {
      y_value_.value = std::move(other.y_value_.value);
    } else {
      field_presence_.Set<1>();
      Construct(&y_value_.value, std::move(other.y_value_.value));
    }
  } else if (field_presence_.IsSet<1>()) {
    field_presence_.Clear<1>();
    Destruct(&y_value_.value);
  }
  if (other.field_presence_.IsSet<2>()) {
    if (field_presence_.IsSet<2>()) {
      x_value_.value = std::move(other.x_value_.value);
    } else {
      field_presence_.Set<2>();
      Construct(&x_value_.value, std::move(other.x_value_.value));
    }
  } else if (field_presence_.IsSet<2>()) {
    field_presence_.Clear<2>();
    Destruct(&x_value_.value);
  }
  _unknown_data = std::move(other._unknown_data);
  return *this;
}

bool ReverseOrdinalTable::IsEmpty() const {
  return field_presence_.IsEmpty() && _unknown_data.size() == 0;
}

void ReverseOrdinalTable::Encode(
    ::fidl::Encoder* _encoder, size_t _offset,
    cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  auto next_unknown = _unknown_data.begin();
  if (field_presence_.IsSet<0>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 1) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &z_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  if (field_presence_.IsSet<1>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 2) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &y_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (2 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  if (field_presence_.IsSet<2>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 3) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &x_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (3 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  // Encode any remaining unknown fields (i.e. ones that have an ordinal outside
  // the range of known ordinals)
  for (auto curr = next_unknown; curr != _unknown_data.end(); ++curr) {
    size_t envelope_base = base + (curr->first - 1) * sizeof(fidl_envelope_t);
    ::fidl::EncodeUnknownBytes(_encoder, &curr->second, envelope_base);
  }
}

void ReverseOrdinalTable::Decode(::fidl::Decoder* _decoder,
                                 ReverseOrdinalTable* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  size_t base;
  size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_z(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_z();
    }
  } else {
    goto done_1;
  }
  if (count >= 2) {
    size_t envelope_base = base + (2 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_y(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_y();
    }
  } else {
    goto done_2;
  }
  if (count >= 3) {
    size_t envelope_base = base + (3 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_x(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_x();
    }
  } else {
    goto done_3;
  }

  if (count > 3) {
    for (uint64_t ordinal = 1; ordinal <= count; ordinal++) {
      if (IsOrdinalKnown(ordinal)) continue;

      size_t envelope_base = base + (ordinal - 1) * sizeof(fidl_envelope_t);
      fidl_envelope_t* envelope =
          _decoder->GetPtr<fidl_envelope_t>(envelope_base);
      if (envelope->presence != 0) {
        auto result = _value->_unknown_data.emplace(
            std::piecewise_construct, std::forward_as_tuple(ordinal),
            std::forward_as_tuple());
        auto iter = result.first;
        iter->second.resize(envelope->num_bytes);
        ::fidl::DecodeUnknownBytesContents(_decoder, &iter->second,
                                           _decoder->GetOffset(envelope->data));
      }
    }
  }

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_z();
done_2:
  _value->clear_y();
done_3:
  _value->clear_x();
  return;
}

zx_status_t ReverseOrdinalTable::Clone(ReverseOrdinalTable* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(z_value_.value, result->mutable_z());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_z();
  }
  if (field_presence_.IsSet<1>()) {
    zx_status_t _status = ::fidl::Clone(y_value_.value, result->mutable_y());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_y();
  }
  if (field_presence_.IsSet<2>()) {
    zx_status_t _status = ::fidl::Clone(x_value_.value, result->mutable_x());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_x();
  }
  return ::fidl::Clone(_unknown_data, &result->_unknown_data);
}

extern "C" const fidl_type_t fidl_test_table_OlderSimpleTableTable;
const fidl_type_t* OlderSimpleTable::FidlType =
    &fidl_test_table_OlderSimpleTableTable;

OlderSimpleTable::OlderSimpleTable() {}

OlderSimpleTable::OlderSimpleTable(OlderSimpleTable&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&x_value_.value, std::move(other.x_value_.value));
  }
  _unknown_data = std::move(other._unknown_data);
}

OlderSimpleTable::~OlderSimpleTable() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&x_value_.value);
  }
}

OlderSimpleTable& OlderSimpleTable::operator=(OlderSimpleTable&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      x_value_.value = std::move(other.x_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&x_value_.value, std::move(other.x_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&x_value_.value);
  }
  _unknown_data = std::move(other._unknown_data);
  return *this;
}

bool OlderSimpleTable::IsEmpty() const {
  return field_presence_.IsEmpty() && _unknown_data.size() == 0;
}

void OlderSimpleTable::Encode(
    ::fidl::Encoder* _encoder, size_t _offset,
    cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  auto next_unknown = _unknown_data.begin();
  if (field_presence_.IsSet<0>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 1) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &x_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  // Encode any remaining unknown fields (i.e. ones that have an ordinal outside
  // the range of known ordinals)
  for (auto curr = next_unknown; curr != _unknown_data.end(); ++curr) {
    size_t envelope_base = base + (curr->first - 1) * sizeof(fidl_envelope_t);
    ::fidl::EncodeUnknownBytes(_encoder, &curr->second, envelope_base);
  }
}

void OlderSimpleTable::Decode(::fidl::Decoder* _decoder,
                              OlderSimpleTable* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  size_t base;
  size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_x(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_x();
    }
  } else {
    goto done_1;
  }

  if (count > 1) {
    for (uint64_t ordinal = 1; ordinal <= count; ordinal++) {
      if (IsOrdinalKnown(ordinal)) continue;

      size_t envelope_base = base + (ordinal - 1) * sizeof(fidl_envelope_t);
      fidl_envelope_t* envelope =
          _decoder->GetPtr<fidl_envelope_t>(envelope_base);
      if (envelope->presence != 0) {
        auto result = _value->_unknown_data.emplace(
            std::piecewise_construct, std::forward_as_tuple(ordinal),
            std::forward_as_tuple());
        auto iter = result.first;
        iter->second.resize(envelope->num_bytes);
        ::fidl::DecodeUnknownBytesContents(_decoder, &iter->second,
                                           _decoder->GetOffset(envelope->data));
      }
    }
  }

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_x();
  return;
}

zx_status_t OlderSimpleTable::Clone(OlderSimpleTable* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(x_value_.value, result->mutable_x());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_x();
  }
  return ::fidl::Clone(_unknown_data, &result->_unknown_data);
}

extern "C" const fidl_type_t fidl_test_table_NewerSimpleTableTable;
const fidl_type_t* NewerSimpleTable::FidlType =
    &fidl_test_table_NewerSimpleTableTable;

NewerSimpleTable::NewerSimpleTable() {}

NewerSimpleTable::NewerSimpleTable(NewerSimpleTable&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&x_value_.value, std::move(other.x_value_.value));
  }
  if (field_presence_.IsSet<4>()) {
    Construct(&y_value_.value, std::move(other.y_value_.value));
  }
  if (field_presence_.IsSet<5>()) {
    Construct(&z_value_.value, std::move(other.z_value_.value));
  }
  _unknown_data = std::move(other._unknown_data);
}

NewerSimpleTable::~NewerSimpleTable() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&x_value_.value);
  }
  if (field_presence_.IsSet<4>()) {
    Destruct(&y_value_.value);
  }
  if (field_presence_.IsSet<5>()) {
    Destruct(&z_value_.value);
  }
}

NewerSimpleTable& NewerSimpleTable::operator=(NewerSimpleTable&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      x_value_.value = std::move(other.x_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&x_value_.value, std::move(other.x_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&x_value_.value);
  }
  if (other.field_presence_.IsSet<4>()) {
    if (field_presence_.IsSet<4>()) {
      y_value_.value = std::move(other.y_value_.value);
    } else {
      field_presence_.Set<4>();
      Construct(&y_value_.value, std::move(other.y_value_.value));
    }
  } else if (field_presence_.IsSet<4>()) {
    field_presence_.Clear<4>();
    Destruct(&y_value_.value);
  }
  if (other.field_presence_.IsSet<5>()) {
    if (field_presence_.IsSet<5>()) {
      z_value_.value = std::move(other.z_value_.value);
    } else {
      field_presence_.Set<5>();
      Construct(&z_value_.value, std::move(other.z_value_.value));
    }
  } else if (field_presence_.IsSet<5>()) {
    field_presence_.Clear<5>();
    Destruct(&z_value_.value);
  }
  _unknown_data = std::move(other._unknown_data);
  return *this;
}

bool NewerSimpleTable::IsEmpty() const {
  return field_presence_.IsEmpty() && _unknown_data.size() == 0;
}

void NewerSimpleTable::Encode(
    ::fidl::Encoder* _encoder, size_t _offset,
    cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  auto next_unknown = _unknown_data.begin();
  if (field_presence_.IsSet<0>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 1) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &x_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  if (field_presence_.IsSet<4>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 5) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &y_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (5 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  if (field_presence_.IsSet<5>()) {
    // Encode unknown fields that have an ordinal that should appear before this
    // field.
    while (next_unknown != _unknown_data.end() && next_unknown->first < 6) {
      size_t envelope_base =
          base + (next_unknown->first - 1) * sizeof(fidl_envelope_t);
      ::fidl::EncodeUnknownBytes(_encoder, &next_unknown->second,
                                 envelope_base);
      std::advance(next_unknown, 1);
    }

    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();
    ::fidl::Encode(
        _encoder, &z_value_.value,
        _encoder->Alloc(
            ::fidl::EncodingInlineSize<int64_t, ::fidl::Encoder>(_encoder)));
    size_t envelope_base = base + (6 - 1) * sizeof(fidl_envelope_t);
    uint64_t num_bytes_then_num_handles =
        (_encoder->CurrentLength() - length_before) |
        ((_encoder->CurrentHandleCount() - handles_before) << 32);
    ::fidl::Encode(_encoder, &num_bytes_then_num_handles, envelope_base);
    *_encoder->GetPtr<uintptr_t>(envelope_base +
                                 offsetof(fidl_envelope_t, presence)) =
        FIDL_ALLOC_PRESENT;
  }
  // Encode any remaining unknown fields (i.e. ones that have an ordinal outside
  // the range of known ordinals)
  for (auto curr = next_unknown; curr != _unknown_data.end(); ++curr) {
    size_t envelope_base = base + (curr->first - 1) * sizeof(fidl_envelope_t);
    ::fidl::EncodeUnknownBytes(_encoder, &curr->second, envelope_base);
  }
}

void NewerSimpleTable::Decode(::fidl::Decoder* _decoder,
                              NewerSimpleTable* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  size_t base;
  size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_x(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_x();
    }
  } else {
    goto done_1;
  }
  if (count >= 5) {
    size_t envelope_base = base + (5 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_y(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_y();
    }
  } else {
    goto done_5;
  }
  if (count >= 6) {
    size_t envelope_base = base + (6 - 1) * sizeof(fidl_envelope_t);
    uint64_t presence;
    ::fidl::Decode(_decoder, &presence,
                   envelope_base + offsetof(fidl_envelope_t, presence));
    if (presence != 0) {
      ::fidl::Decode(_decoder, _value->mutable_z(),
                     _decoder->GetOffset(presence));
    } else {
      _value->clear_z();
    }
  } else {
    goto done_6;
  }

  if (count > 3) {
    for (uint64_t ordinal = 1; ordinal <= count; ordinal++) {
      if (IsOrdinalKnown(ordinal)) continue;

      size_t envelope_base = base + (ordinal - 1) * sizeof(fidl_envelope_t);
      fidl_envelope_t* envelope =
          _decoder->GetPtr<fidl_envelope_t>(envelope_base);
      if (envelope->presence != 0) {
        auto result = _value->_unknown_data.emplace(
            std::piecewise_construct, std::forward_as_tuple(ordinal),
            std::forward_as_tuple());
        auto iter = result.first;
        iter->second.resize(envelope->num_bytes);
        ::fidl::DecodeUnknownBytesContents(_decoder, &iter->second,
                                           _decoder->GetOffset(envelope->data));
      }
    }
  }

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_x();
done_5:
  _value->clear_y();
done_6:
  _value->clear_z();
  return;
}

zx_status_t NewerSimpleTable::Clone(NewerSimpleTable* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(x_value_.value, result->mutable_x());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_x();
  }
  if (field_presence_.IsSet<4>()) {
    zx_status_t _status = ::fidl::Clone(y_value_.value, result->mutable_y());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_y();
  }
  if (field_presence_.IsSet<5>()) {
    zx_status_t _status = ::fidl::Clone(z_value_.value, result->mutable_z());
    if (_status != ZX_OK) return _status;
  } else {
    result->clear_z();
  }
  return ::fidl::Clone(_unknown_data, &result->_unknown_data);
}

extern "C" const fidl_type_t fidl_test_table_EmptyTableTable;
const fidl_type_t* EmptyTable::FidlType = &fidl_test_table_EmptyTableTable;

EmptyTable::EmptyTable() {}

EmptyTable::EmptyTable(EmptyTable&& other) {
  field_presence_ = other.field_presence_;
  _unknown_data = std::move(other._unknown_data);
}

EmptyTable::~EmptyTable() {}

EmptyTable& EmptyTable::operator=(EmptyTable&& other) {
  _unknown_data = std::move(other._unknown_data);
  return *this;
}

bool EmptyTable::IsEmpty() const {
  return field_presence_.IsEmpty() && _unknown_data.size() == 0;
}

void EmptyTable::Encode(
    ::fidl::Encoder* _encoder, size_t _offset,
    cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  auto next_unknown = _unknown_data.begin();
  // Encode any remaining unknown fields (i.e. ones that have an ordinal outside
  // the range of known ordinals)
  for (auto curr = next_unknown; curr != _unknown_data.end(); ++curr) {
    size_t envelope_base = base + (curr->first - 1) * sizeof(fidl_envelope_t);
    ::fidl::EncodeUnknownBytes(_encoder, &curr->second, envelope_base);
  }
}

void EmptyTable::Decode(::fidl::Decoder* _decoder, EmptyTable* _value,
                        size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  size_t base;
  size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;

  if (count > 0) {
    for (uint64_t ordinal = 1; ordinal <= count; ordinal++) {
      if (IsOrdinalKnown(ordinal)) continue;

      size_t envelope_base = base + (ordinal - 1) * sizeof(fidl_envelope_t);
      fidl_envelope_t* envelope =
          _decoder->GetPtr<fidl_envelope_t>(envelope_base);
      if (envelope->presence != 0) {
        auto result = _value->_unknown_data.emplace(
            std::piecewise_construct, std::forward_as_tuple(ordinal),
            std::forward_as_tuple());
        auto iter = result.first;
        iter->second.resize(envelope->num_bytes);
        ::fidl::DecodeUnknownBytesContents(_decoder, &iter->second,
                                           _decoder->GetOffset(envelope->data));
      }
    }
  }

  return;

  // Clear unset values.
clear_all:
  return;
}

zx_status_t EmptyTable::Clone(EmptyTable* result) const {
  return ::fidl::Clone(_unknown_data, &result->_unknown_data);
}

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