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

// fidl_experiment = output_index_json

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

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

//
// Domain objects definitions
//
namespace test {
namespace aliases {

#ifdef __Fuchsia__

extern "C" const fidl_type_t test_aliases_ExampleOfUseOfAliasesTable;
const fidl_type_t* ExampleOfUseOfAliases::FidlType = &test_aliases_ExampleOfUseOfAliasesTable;

void ExampleOfUseOfAliases::Encode(::fidl::Encoder* _encoder, size_t _offset,
                                   cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  if (::fidl::IsMemcpyCompatible<ExampleOfUseOfAliases>::value) {
    memcpy(_encoder->template GetPtr<ExampleOfUseOfAliases>(_offset), this, sizeof(ExampleOfUseOfAliases));
  } else {
    ::fidl::Encode(_encoder, &field_of_u32, _offset + 0);
    ::fidl::Encode(_encoder, &field_of_vec_of_strings, _offset + 8);
    ::fidl::Encode(_encoder, &field_of_vec_of_strings_at_most_nine, _offset + 24);
    ::fidl::Encode(_encoder, &field_of_vec_of_strings_at_most_5, _offset + 40);
    ::fidl::Encode(_encoder, &field_of_vec_of_ref_me_at_most_5, _offset + 56);

    ::fidl::Encode(_encoder, &field_of_channel, _offset + 72, ::fidl::HandleInformation{
                                                                  .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                  .rights = 0x80000000,
                                                              });

    ::fidl::Encode(_encoder, &field_of_client_end, _offset + 76, ::fidl::HandleInformation{
                                                                     .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                     .rights = 0x80000000,
                                                                 });

    ::fidl::Encode(_encoder, &field_of_nullable_client_end, _offset + 80, ::fidl::HandleInformation{
                                                                              .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                              .rights = 0x80000000,
                                                                          });
  }
}

void ExampleOfUseOfAliases::Decode(::fidl::Decoder* _decoder, ExampleOfUseOfAliases* _value, size_t _offset) {
  if (::fidl::IsMemcpyCompatible<ExampleOfUseOfAliases>::value) {
    memcpy(_value, _decoder->template GetPtr<ExampleOfUseOfAliases>(_offset), sizeof(ExampleOfUseOfAliases));
  } else {
    ::fidl::Decode(_decoder, &_value->field_of_u32, _offset + 0);
    ::fidl::Decode(_decoder, &_value->field_of_vec_of_strings, _offset + 8);
    ::fidl::Decode(_decoder, &_value->field_of_vec_of_strings_at_most_nine, _offset + 24);
    ::fidl::Decode(_decoder, &_value->field_of_vec_of_strings_at_most_5, _offset + 40);
    ::fidl::Decode(_decoder, &_value->field_of_vec_of_ref_me_at_most_5, _offset + 56);
    ::fidl::Decode(_decoder, &_value->field_of_channel, _offset + 72);
    ::fidl::Decode(_decoder, &_value->field_of_client_end, _offset + 76);
    ::fidl::Decode(_decoder, &_value->field_of_nullable_client_end, _offset + 80);
  }
}

zx_status_t ExampleOfUseOfAliases::Clone(ExampleOfUseOfAliases* _result) const {
  zx_status_t _status = ::fidl::Clone(field_of_u32, &_result->field_of_u32);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_vec_of_strings, &_result->field_of_vec_of_strings);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_vec_of_strings_at_most_nine, &_result->field_of_vec_of_strings_at_most_nine);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_vec_of_strings_at_most_5, &_result->field_of_vec_of_strings_at_most_5);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_vec_of_ref_me_at_most_5, &_result->field_of_vec_of_ref_me_at_most_5);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_channel, &_result->field_of_channel);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_client_end, &_result->field_of_client_end);
  if (_status != ZX_OK)
    return _status;
  _status = ::fidl::Clone(field_of_nullable_client_end, &_result->field_of_nullable_client_end);
  if (_status != ZX_OK)
    return _status;
  return ZX_OK;
}

#endif  // __Fuchsia__

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