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

// fidl_experiment = output_index_json

#include <test/handlesintypes/cpp/fidl.h>

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

//
// Domain objects definitions
//
namespace test {
namespace handlesintypes {

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_TableWithHandleTable;
const fidl_type_t* TableWithHandle::FidlType = &test_handlesintypes_TableWithHandleTable;

TableWithHandle::TableWithHandle() {}

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

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

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

bool TableWithHandle::IsEmpty() const {
  return field_presence_.IsEmpty();
}
TableWithHandle& TableWithHandle::set_h(::zx::vmo _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&h_value_.value, std::move(_value));
  } else {
    h_value_.value = std::move(_value);
  }
  return *this;
}

void TableWithHandle::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;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<::zx::vmo>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &h_value_.value, envelope_base, ::fidl::HandleInformation{.object_type = ZX_OBJ_TYPE_VMO, .rights = 0x80000000});

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
          _encoder,
          &h_value_.value,
          _encoder->Alloc(::fidl::EncodingInlineSize<::zx::vmo, ::fidl::Encoder>(_encoder)), ::fidl::HandleInformation{.object_type = ZX_OBJ_TYPE_VMO, .rights = 0x80000000});

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void TableWithHandle::Decode(::fidl::Decoder* _decoder, TableWithHandle* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] 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);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_h(),
                     _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_h();
    }
  } 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);
      _decoder->CloseUnknownHandlesInEnvelope(envelope);
    }
  }

  return;

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

zx_status_t TableWithHandle::Clone(TableWithHandle* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(h_value_.value, result->mutable_h());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_h();
  }
  return ZX_OK;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_UnionWithHandleTable;
const fidl_type_t* UnionWithHandle::FidlType = &test_handlesintypes_UnionWithHandleTable;

UnionWithHandle::UnionWithHandle() {}

UnionWithHandle::~UnionWithHandle() {
  Destroy();
}

UnionWithHandle::UnionWithHandle(UnionWithHandle&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::handlesintypes::UnionWithHandle::Tag::kH:
      new (&h_)::zx::vmo();
      h_ = std::move(other.h_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::UnionWithHandle::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

UnionWithHandle& UnionWithHandle::operator=(UnionWithHandle&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::handlesintypes::UnionWithHandle::Tag::kH:
        new (&h_)::zx::vmo();
        h_ = std::move(other.h_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::UnionWithHandle::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

UnionWithHandle UnionWithHandle::WithH(::zx::vmo&& val) {
  UnionWithHandle result;
  result.set_h(std::move(val));
  return result;
}

void UnionWithHandle::Encode(::fidl::Encoder* encoder, size_t offset,
                             cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::handlesintypes::UnionWithHandle::Tag::kH: {
      if (::fidl::EncodingInlineSize<::zx::vmo>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &h_, offset + offsetof(fidl_union_t, envelope), ::fidl::HandleInformation{.object_type = ZX_OBJ_TYPE_VMO, .rights = 0x80000000});

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
          encoder,
          &h_,
          encoder->Alloc(::fidl::EncodingInlineSize<::zx::vmo, ::fidl::Encoder>(encoder)), ::fidl::HandleInformation{.object_type = ZX_OBJ_TYPE_VMO, .rights = 0x80000000});

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::handlesintypes::UnionWithHandle::Tag::kUnknown: {
      ::fidl::EncodeUnknownData(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void UnionWithHandle::Decode(::fidl::Decoder* _decoder, UnionWithHandle* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::handlesintypes::UnionWithHandle::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);

  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::handlesintypes::UnionWithHandle::Tag::kH: {
      value->h_.~decltype(value->h_)();
      new (&value->h_)::zx::vmo();
      ::fidl::Decode(_decoder, &value->h_, value_offset);
      break;
    }
    default: {
      auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.bytes.resize(unknown_info.num_bytes);
      value->unknown_data_.handles.resize(unknown_info.num_handles);
      ::fidl::DecodeUnknownDataContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
      break;
    }
  }
}

zx_status_t UnionWithHandle::Clone(UnionWithHandle* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::handlesintypes::UnionWithHandle::Tag::Invalid:
      return ZX_OK;
    case ::test::handlesintypes::UnionWithHandle::Tag::kH:
      new (&result->h_)::zx::vmo();
      return ::fidl::Clone(h_, &result->h_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}

UnionWithHandle& UnionWithHandle::set_h(::zx::vmo value) {
  EnsureStorageInitialized(::test::handlesintypes::UnionWithHandle::Tag::kH);
  h_ = std::move(value);
  return *this;
}
UnionWithHandle& UnionWithHandle::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes, std::vector<zx::handle> handles) {
  EnsureStorageInitialized(ordinal);
  unknown_data_.bytes = std::move(bytes);
  unknown_data_.handles = std::move(handles);
  return *this;
}

void UnionWithHandle::Destroy() {
  switch (tag_) {
    case ::test::handlesintypes::UnionWithHandle::Tag::kH:
      h_.~decltype(h_)();
      break;

    case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::UnionWithHandle::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::handlesintypes::UnionWithHandle::Tag::Invalid);
}

void UnionWithHandle::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::UnionWithHandle::Tag::Invalid):
        break;
      case ::test::handlesintypes::UnionWithHandle::Tag::kH:
        new (&h_)::zx::vmo();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_HandlesInTypesTable;
const fidl_type_t* HandlesInTypes::FidlType = &test_handlesintypes_HandlesInTypesTable;

void HandlesInTypes::Encode(::fidl::Encoder* _encoder, size_t _offset,
                            cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<HandlesInTypes>::value) {
    memcpy(_encoder->template GetPtr<HandlesInTypes>(_offset), this, sizeof(HandlesInTypes));
  } else {
    ::fidl::Encode(_encoder, &normal_handle, _offset + 0, ::fidl::HandleInformation{
                                                              .object_type = ZX_OBJ_TYPE_VMO,
                                                              .rights = 0x80000000,
                                                          });

    ::fidl::Encode(_encoder, &handle_in_vec, _offset + 8, ::fidl::HandleInformation{
                                                              .object_type = ZX_OBJ_TYPE_VMO,
                                                              .rights = 0x80000000,
                                                          });

    ::fidl::Encode(_encoder, &handle_in_array, _offset + 24, ::fidl::HandleInformation{
                                                                 .object_type = ZX_OBJ_TYPE_VMO,
                                                                 .rights = 0x80000000,
                                                             });

    ::fidl::Encode(_encoder, &handle_in_mixed_vec_array, _offset + 48, ::fidl::HandleInformation{
                                                                           .object_type = ZX_OBJ_TYPE_VMO,
                                                                           .rights = 0x80000000,
                                                                       });
    ::fidl::Encode(_encoder, &table_with_handle, _offset + 64);
    ::fidl::Encode(_encoder, &union_with_handle, _offset + 80);
  }
}

void HandlesInTypes::Decode(::fidl::Decoder* _decoder, HandlesInTypes* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<HandlesInTypes>::value) {
    memcpy(_value, _decoder->template GetPtr<HandlesInTypes>(_offset), sizeof(HandlesInTypes));
  } else {
    ::fidl::Decode(_decoder, &_value->normal_handle, _offset + 0);
    ::fidl::Decode(_decoder, &_value->handle_in_vec, _offset + 8);
    ::fidl::Decode(_decoder, &_value->handle_in_array, _offset + 24);
    ::fidl::Decode(_decoder, &_value->handle_in_mixed_vec_array, _offset + 48);
    ::fidl::Decode(_decoder, &_value->table_with_handle, _offset + 64);
    ::fidl::Decode(_decoder, &_value->union_with_handle, _offset + 80);
  }
}

zx_status_t HandlesInTypes::Clone(HandlesInTypes* _result) const {
  zx_status_t _status = ::fidl::Clone(normal_handle, &_result->normal_handle);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(handle_in_vec, &_result->handle_in_vec);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(handle_in_array, &_result->handle_in_array);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(handle_in_mixed_vec_array, &_result->handle_in_mixed_vec_array);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(table_with_handle, &_result->table_with_handle);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(union_with_handle, &_result->union_with_handle);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_EmptyResourceStructTable;
const fidl_type_t* EmptyResourceStruct::FidlType = &test_handlesintypes_EmptyResourceStructTable;

void EmptyResourceStruct::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                 cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<EmptyResourceStruct>::value) {
    memcpy(_encoder->template GetPtr<EmptyResourceStruct>(_offset), this, sizeof(EmptyResourceStruct));
  } else {
    ::fidl::Encode(_encoder, &__reserved, _offset + 0);
  }
}

void EmptyResourceStruct::Decode(::fidl::Decoder* _decoder, EmptyResourceStruct* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<EmptyResourceStruct>::value) {
    memcpy(_value, _decoder->template GetPtr<EmptyResourceStruct>(_offset), sizeof(EmptyResourceStruct));
  } else {
    ::fidl::Decode(_decoder, &_value->__reserved, _offset + 0);
  }
}

zx_status_t EmptyResourceStruct::Clone(EmptyResourceStruct* _result) const {
  zx_status_t _status = ::fidl::Clone(__reserved, &_result->__reserved);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_EmptyResourceTableTable;
const fidl_type_t* EmptyResourceTable::FidlType = &test_handlesintypes_EmptyResourceTableTable;

EmptyResourceTable::EmptyResourceTable() {}

EmptyResourceTable::EmptyResourceTable(EmptyResourceTable&& other) {
  field_presence_ = other.field_presence_;
}

EmptyResourceTable::~EmptyResourceTable() {
}

EmptyResourceTable& EmptyResourceTable::operator=(EmptyResourceTable&& other) {
  return *this;
}

bool EmptyResourceTable::IsEmpty() const {
  return field_presence_.IsEmpty();
}

void EmptyResourceTable::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;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
}

void EmptyResourceTable::Decode(::fidl::Decoder* _decoder, EmptyResourceTable* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] 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);
      _decoder->CloseUnknownHandlesInEnvelope(envelope);
    }
  }

  return;

  // Clear unset values.
clear_all:
  return;
}

zx_status_t EmptyResourceTable::Clone(EmptyResourceTable* result) const {
  return ZX_OK;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_handlesintypes_EmptyResourceUnionTable;
const fidl_type_t* EmptyResourceUnion::FidlType = &test_handlesintypes_EmptyResourceUnionTable;

EmptyResourceUnion::EmptyResourceUnion() {}

EmptyResourceUnion::~EmptyResourceUnion() {
  Destroy();
}

EmptyResourceUnion::EmptyResourceUnion(EmptyResourceUnion&& other) : tag_(other.tag_) {
  switch (tag_) {
    case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::EmptyResourceUnion::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

EmptyResourceUnion& EmptyResourceUnion::operator=(EmptyResourceUnion&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::EmptyResourceUnion::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_ = std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

void EmptyResourceUnion::Encode(::fidl::Encoder* encoder, size_t offset,
                                cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  switch (Which()) {
    case ::test::handlesintypes::EmptyResourceUnion::Tag::kUnknown: {
      ::fidl::EncodeUnknownData(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void EmptyResourceUnion::Decode(::fidl::Decoder* _decoder, EmptyResourceUnion* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::handlesintypes::EmptyResourceUnion::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);
}

zx_status_t EmptyResourceUnion::Clone(EmptyResourceUnion* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::handlesintypes::EmptyResourceUnion::Tag::Invalid:
      return ZX_OK;
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
      return ZX_OK;
  }
}
EmptyResourceUnion& EmptyResourceUnion::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes, std::vector<zx::handle> handles) {
  EnsureStorageInitialized(ordinal);
  unknown_data_.bytes = std::move(bytes);
  unknown_data_.handles = std::move(handles);
  return *this;
}

void EmptyResourceUnion::Destroy() {
  switch (tag_) {
    case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::EmptyResourceUnion::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::handlesintypes::EmptyResourceUnion::Tag::Invalid);
}

void EmptyResourceUnion::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::handlesintypes::EmptyResourceUnion::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

#endif  // __Fuchsia__

//
// Proxies and stubs definitions
//
}  // namespace handlesintypes
}  // namespace test
