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

library fidl_fidl_test_byteandbytes_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 ByteAndBytes extends $fidl.Struct {
  const ByteAndBytes({
    required this.singleByte,
    required this.manyBytes,
    required this.onlyOneKBytes,
    this.optOnlyOneKBytes,
  });
  ByteAndBytes.clone(
    ByteAndBytes $orig, {
    int? singleByte,
    Uint8List? manyBytes,
    Uint8List? onlyOneKBytes,
    Uint8List? optOnlyOneKBytes,
  }) : this(
          singleByte: singleByte ?? $orig.singleByte,
          manyBytes: manyBytes ?? $orig.manyBytes,
          onlyOneKBytes: onlyOneKBytes ?? $orig.onlyOneKBytes,
          optOnlyOneKBytes: optOnlyOneKBytes ?? $orig.optOnlyOneKBytes,
        );

  ByteAndBytes.cloneWithout(
    ByteAndBytes $orig, {
    bool optOnlyOneKBytes = false,
  }) : this(
          singleByte: $orig.singleByte,
          manyBytes: $orig.manyBytes,
          onlyOneKBytes: $orig.onlyOneKBytes,
          optOnlyOneKBytes: optOnlyOneKBytes ? null : $orig.optOnlyOneKBytes,
        );

  final int singleByte;
  final Uint8List manyBytes;
  final Uint8List onlyOneKBytes;
  final Uint8List? optOnlyOneKBytes;

  @override
  List<Object?> get $fields {
    return <Object?>[
      singleByte,
      manyBytes,
      onlyOneKBytes,
      optOnlyOneKBytes,
    ];
  }

  static const $fieldType0 = $fidl.Uint8Type();
  static const $fieldType1 = $fidl.VectorType<int, Uint8List>(
      element: $fidl.Uint8Type(), maybeElementCount: null);
  static const $fieldType2 = $fidl.VectorType<int, Uint8List>(
      element: $fidl.Uint8Type(), maybeElementCount: 1024);
  static const $fieldType3 = $fidl.NullableVectorType<int, Uint8List>(
      element: $fidl.Uint8Type(), maybeElementCount: 1024);

  @override
  void $encode($fidl.Encoder $encoder, int $offset, int $depth) {
    $fieldType0.encode($encoder, singleByte, $offset + 0, $depth);
    $fieldType1.encode($encoder, manyBytes, $offset + 8, $depth);
    $fieldType2.encode($encoder, onlyOneKBytes, $offset + 24, $depth);
    $fieldType3.encode($encoder, optOnlyOneKBytes, $offset + 40, $depth);
  }

  @override
  String toString() {
    return r'ByteAndBytes' r'(singleByte: ' +
        singleByte.toString() +
        r', manyBytes: ' +
        manyBytes.toString() +
        r', onlyOneKBytes: ' +
        onlyOneKBytes.toString() +
        r', optOnlyOneKBytes: ' +
        optOnlyOneKBytes.toString() +
        r')';
  }

  static ByteAndBytes _structDecode(
      $fidl.Decoder $decoder, int $offset, int $depth) {
    return ByteAndBytes(
        singleByte: $fieldType0.decode($decoder, $offset + 0, $depth),
        manyBytes: $fieldType1.decode($decoder, $offset + 8, $depth),
        onlyOneKBytes: $fieldType2.decode($decoder, $offset + 24, $depth),
        optOnlyOneKBytes: $fieldType3.decode($decoder, $offset + 40, $depth));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ByteAndBytes> kByteAndBytes_Type =
    $fidl.StructType<ByteAndBytes>(
  inlineSize: 56,
  structDecode: ByteAndBytes._structDecode,
);

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