// WARNING: This file is machine generated by fidlgen_dart.
// @dart = 2.8

library fidl_fidl_test_vectors_async;

import 'dart:async' as $async;
import 'dart:core' hide Set;
import 'dart:developer';
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as $fidl;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart' as $zircon;

// ignore_for_file: always_specify_types
// ignore_for_file: avoid_positional_boolean_parameters
// ignore_for_file: avoid_returning_null
// ignore_for_file: cascade_invocations
// ignore_for_file: constant_identifier_names
// ignore_for_file: one_member_abstracts
// ignore_for_file: prefer_constructors_over_static_methods
// ignore_for_file: prefer_single_quotes
// ignore_for_file: public_member_api_docs
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: library_prefixes
// ignore_for_file: prefer_typing_uninitialized_variables
// ignore_for_file: avoid_js_rounded_ints
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: prefer_generic_function_type_aliases
// ignore_for_file: prefer_equal_for_default_values
// ignore_for_file: avoid_catches_without_on_clauses
// ignore_for_file: unused_shown_name
// ignore_for_file: unnecessary_lambdas
// ignore_for_file: comment_references
// ignore_for_file: avoid_unused_constructor_parameters
// ignore_for_file: prefer_interpolation_to_compose_strings

class ExampleUseOfVectors extends $fidl.Struct {
  const ExampleUseOfVectors({
    @required this.vectorOfUint8,
    @required this.vectorOfVectorOfBool,
  });
  ExampleUseOfVectors.clone(
    ExampleUseOfVectors $orig, {
    Uint8List vectorOfUint8,
    List<List<bool>> vectorOfVectorOfBool,
  }) : this(
          vectorOfUint8: vectorOfUint8 ?? $orig.vectorOfUint8,
          vectorOfVectorOfBool:
              vectorOfVectorOfBool ?? $orig.vectorOfVectorOfBool,
        );

  final Uint8List vectorOfUint8;
  final List<List<bool>> vectorOfVectorOfBool;

  @override
  List<Object> get $fields {
    return <Object>[
      vectorOfUint8,
      vectorOfVectorOfBool,
    ];
  }

  static const $fieldType0 = $fidl.VectorType<Uint8List>(
      element: $fidl.Uint8Type(), maybeElementCount: null, nullable: false);
  static const $fieldType1 = $fidl.VectorType<List<List<bool>>>(
      element: $fidl.VectorType<List<bool>>(
          element: $fidl.BoolType(), maybeElementCount: null, nullable: false),
      maybeElementCount: null,
      nullable: false);

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, vectorOfUint8, $offset + 0);
    $fieldType1.encode($encoder, vectorOfVectorOfBool, $offset + 16);
  }

  @override
  String toString() {
    return r'ExampleUseOfVectors' r'(vectorOfUint8: ' +
        vectorOfUint8.toString() +
        r', vectorOfVectorOfBool: ' +
        vectorOfVectorOfBool.toString() +
        r')';
  }

  static ExampleUseOfVectors _structDecode(
      $fidl.Decoder $decoder, int $offset) {
    return ExampleUseOfVectors(
        vectorOfUint8: $fieldType0.decode($decoder, $offset + 0),
        vectorOfVectorOfBool: $fieldType1.decode($decoder, $offset + 16));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ExampleUseOfVectors> kExampleUseOfVectors_Type =
    $fidl.StructType<ExampleUseOfVectors>(
  inlineSize: 32,
  structDecode: ExampleUseOfVectors._structDecode,
);

// ignore: unused_element, avoid_private_typedef_functions
typedef _VoidCallback = void Function();
