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

library fidl_fidl_test_padding_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 Padding1ByteEnd extends $fidl.Struct {
  const Padding1ByteEnd({
    required this.a,
    required this.b,
  });
  Padding1ByteEnd.clone(
    Padding1ByteEnd $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint16Type();
  static const $fieldType1 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 2);
  }

  @override
  String toString() {
    return r'Padding1ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding1ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding1ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 2));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding1ByteEnd> kPadding1ByteEnd_Type =
    $fidl.StructType<Padding1ByteEnd>(
  inlineSize: 4,
  structDecode: Padding1ByteEnd._structDecode,
);

class Padding2ByteEnd extends $fidl.Struct {
  const Padding2ByteEnd({
    required this.a,
    required this.b,
  });
  Padding2ByteEnd.clone(
    Padding2ByteEnd $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint32Type();
  static const $fieldType1 = $fidl.Uint16Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 4);
  }

  @override
  String toString() {
    return r'Padding2ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding2ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding2ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 4));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding2ByteEnd> kPadding2ByteEnd_Type =
    $fidl.StructType<Padding2ByteEnd>(
  inlineSize: 8,
  structDecode: Padding2ByteEnd._structDecode,
);

class Padding3ByteEnd extends $fidl.Struct {
  const Padding3ByteEnd({
    required this.a,
    required this.b,
  });
  Padding3ByteEnd.clone(
    Padding3ByteEnd $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint32Type();
  static const $fieldType1 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 4);
  }

  @override
  String toString() {
    return r'Padding3ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding3ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding3ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 4));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding3ByteEnd> kPadding3ByteEnd_Type =
    $fidl.StructType<Padding3ByteEnd>(
  inlineSize: 8,
  structDecode: Padding3ByteEnd._structDecode,
);

class Padding4ByteEnd extends $fidl.Struct {
  const Padding4ByteEnd({
    required this.a,
    required this.b,
  });
  Padding4ByteEnd.clone(
    Padding4ByteEnd $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint64Type();
  static const $fieldType1 = $fidl.Uint32Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding4ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding4ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding4ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding4ByteEnd> kPadding4ByteEnd_Type =
    $fidl.StructType<Padding4ByteEnd>(
  inlineSize: 16,
  structDecode: Padding4ByteEnd._structDecode,
);

class Padding5ByteEnd extends $fidl.Struct {
  const Padding5ByteEnd({
    required this.a,
    required this.b,
    required this.c,
  });
  Padding5ByteEnd.clone(
    Padding5ByteEnd $orig, {
    int? a,
    int? b,
    int? c,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
          c: c ?? $orig.c,
        );

  final int a;
  final int b;
  final int c;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
      c,
    ];
  }

  static const $fieldType0 = $fidl.Uint64Type();
  static const $fieldType1 = $fidl.Uint16Type();
  static const $fieldType2 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
    $fieldType2.encode($encoder, c, $offset + 10);
  }

  @override
  String toString() {
    return r'Padding5ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r', c: ' +
        c.toString() +
        r')';
  }

  static Padding5ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding5ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8),
        c: $fieldType2.decode($decoder, $offset + 10));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding5ByteEnd> kPadding5ByteEnd_Type =
    $fidl.StructType<Padding5ByteEnd>(
  inlineSize: 16,
  structDecode: Padding5ByteEnd._structDecode,
);

class Padding6ByteEnd extends $fidl.Struct {
  const Padding6ByteEnd({
    required this.a,
    required this.b,
  });
  Padding6ByteEnd.clone(
    Padding6ByteEnd $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint64Type();
  static const $fieldType1 = $fidl.Uint16Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding6ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding6ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding6ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding6ByteEnd> kPadding6ByteEnd_Type =
    $fidl.StructType<Padding6ByteEnd>(
  inlineSize: 16,
  structDecode: Padding6ByteEnd._structDecode,
);

class Padding7ByteEnd extends $fidl.Struct {
  const Padding7ByteEnd({
    required this.a,
    required this.b,
  });
  Padding7ByteEnd.clone(
    Padding7ByteEnd $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint64Type();
  static const $fieldType1 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding7ByteEnd' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding7ByteEnd _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding7ByteEnd(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding7ByteEnd> kPadding7ByteEnd_Type =
    $fidl.StructType<Padding7ByteEnd>(
  inlineSize: 16,
  structDecode: Padding7ByteEnd._structDecode,
);

class Padding1ByteMiddle extends $fidl.Struct {
  const Padding1ByteMiddle({
    required this.a,
    required this.b,
  });
  Padding1ByteMiddle.clone(
    Padding1ByteMiddle $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint8Type();
  static const $fieldType1 = $fidl.Uint16Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 2);
  }

  @override
  String toString() {
    return r'Padding1ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding1ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding1ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 2));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding1ByteMiddle> kPadding1ByteMiddle_Type =
    $fidl.StructType<Padding1ByteMiddle>(
  inlineSize: 4,
  structDecode: Padding1ByteMiddle._structDecode,
);

class Padding2ByteMiddle extends $fidl.Struct {
  const Padding2ByteMiddle({
    required this.a,
    required this.b,
  });
  Padding2ByteMiddle.clone(
    Padding2ByteMiddle $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint16Type();
  static const $fieldType1 = $fidl.Uint32Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 4);
  }

  @override
  String toString() {
    return r'Padding2ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding2ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding2ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 4));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding2ByteMiddle> kPadding2ByteMiddle_Type =
    $fidl.StructType<Padding2ByteMiddle>(
  inlineSize: 8,
  structDecode: Padding2ByteMiddle._structDecode,
);

class Padding3ByteMiddle extends $fidl.Struct {
  const Padding3ByteMiddle({
    required this.a,
    required this.b,
  });
  Padding3ByteMiddle.clone(
    Padding3ByteMiddle $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint8Type();
  static const $fieldType1 = $fidl.Uint32Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 4);
  }

  @override
  String toString() {
    return r'Padding3ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding3ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding3ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 4));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding3ByteMiddle> kPadding3ByteMiddle_Type =
    $fidl.StructType<Padding3ByteMiddle>(
  inlineSize: 8,
  structDecode: Padding3ByteMiddle._structDecode,
);

class Padding4ByteMiddle extends $fidl.Struct {
  const Padding4ByteMiddle({
    required this.a,
    required this.b,
  });
  Padding4ByteMiddle.clone(
    Padding4ByteMiddle $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint32Type();
  static const $fieldType1 = $fidl.Uint64Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding4ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding4ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding4ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding4ByteMiddle> kPadding4ByteMiddle_Type =
    $fidl.StructType<Padding4ByteMiddle>(
  inlineSize: 16,
  structDecode: Padding4ByteMiddle._structDecode,
);

class Padding5ByteMiddle extends $fidl.Struct {
  const Padding5ByteMiddle({
    required this.a,
    required this.b,
    required this.c,
  });
  Padding5ByteMiddle.clone(
    Padding5ByteMiddle $orig, {
    int? a,
    int? b,
    int? c,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
          c: c ?? $orig.c,
        );

  final int a;
  final int b;
  final int c;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
      c,
    ];
  }

  static const $fieldType0 = $fidl.Uint16Type();
  static const $fieldType1 = $fidl.Uint8Type();
  static const $fieldType2 = $fidl.Uint64Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 2);
    $fieldType2.encode($encoder, c, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding5ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r', c: ' +
        c.toString() +
        r')';
  }

  static Padding5ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding5ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 2),
        c: $fieldType2.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding5ByteMiddle> kPadding5ByteMiddle_Type =
    $fidl.StructType<Padding5ByteMiddle>(
  inlineSize: 16,
  structDecode: Padding5ByteMiddle._structDecode,
);

class Padding6ByteMiddle extends $fidl.Struct {
  const Padding6ByteMiddle({
    required this.a,
    required this.b,
  });
  Padding6ByteMiddle.clone(
    Padding6ByteMiddle $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint16Type();
  static const $fieldType1 = $fidl.Uint64Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding6ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding6ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding6ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding6ByteMiddle> kPadding6ByteMiddle_Type =
    $fidl.StructType<Padding6ByteMiddle>(
  inlineSize: 16,
  structDecode: Padding6ByteMiddle._structDecode,
);

class Padding7ByteMiddle extends $fidl.Struct {
  const Padding7ByteMiddle({
    required this.a,
    required this.b,
  });
  Padding7ByteMiddle.clone(
    Padding7ByteMiddle $orig, {
    int? a,
    int? b,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
        );

  final int a;
  final int b;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
    ];
  }

  static const $fieldType0 = $fidl.Uint8Type();
  static const $fieldType1 = $fidl.Uint64Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding7ByteMiddle' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r')';
  }

  static Padding7ByteMiddle _structDecode($fidl.Decoder $decoder, int $offset) {
    return Padding7ByteMiddle(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding7ByteMiddle> kPadding7ByteMiddle_Type =
    $fidl.StructType<Padding7ByteMiddle>(
  inlineSize: 16,
  structDecode: Padding7ByteMiddle._structDecode,
);

class Padding4ByteAlignmentLength12 extends $fidl.Struct {
  const Padding4ByteAlignmentLength12({
    required this.a,
    required this.b,
    required this.c,
    required this.d,
  });
  Padding4ByteAlignmentLength12.clone(
    Padding4ByteAlignmentLength12 $orig, {
    int? a,
    int? b,
    int? c,
    int? d,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
          c: c ?? $orig.c,
          d: d ?? $orig.d,
        );

  final int a;
  final int b;
  final int c;
  final int d;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
      c,
      d,
    ];
  }

  static const $fieldType0 = $fidl.Uint32Type();
  static const $fieldType1 = $fidl.Uint8Type();
  static const $fieldType2 = $fidl.Uint16Type();
  static const $fieldType3 = $fidl.Uint16Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 4);
    $fieldType2.encode($encoder, c, $offset + 6);
    $fieldType3.encode($encoder, d, $offset + 8);
  }

  @override
  String toString() {
    return r'Padding4ByteAlignmentLength12' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r', c: ' +
        c.toString() +
        r', d: ' +
        d.toString() +
        r')';
  }

  static Padding4ByteAlignmentLength12 _structDecode(
      $fidl.Decoder $decoder, int $offset) {
    return Padding4ByteAlignmentLength12(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 4),
        c: $fieldType2.decode($decoder, $offset + 6),
        d: $fieldType3.decode($decoder, $offset + 8));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding4ByteAlignmentLength12>
    kPadding4ByteAlignmentLength12_Type =
    $fidl.StructType<Padding4ByteAlignmentLength12>(
  inlineSize: 12,
  structDecode: Padding4ByteAlignmentLength12._structDecode,
);

class Padding2ByteAlignmentLength6 extends $fidl.Struct {
  const Padding2ByteAlignmentLength6({
    required this.a,
    required this.b,
    required this.c,
  });
  Padding2ByteAlignmentLength6.clone(
    Padding2ByteAlignmentLength6 $orig, {
    int? a,
    int? b,
    int? c,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
          c: c ?? $orig.c,
        );

  final int a;
  final int b;
  final int c;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
      c,
    ];
  }

  static const $fieldType0 = $fidl.Uint8Type();
  static const $fieldType1 = $fidl.Uint16Type();
  static const $fieldType2 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 2);
    $fieldType2.encode($encoder, c, $offset + 4);
  }

  @override
  String toString() {
    return r'Padding2ByteAlignmentLength6' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r', c: ' +
        c.toString() +
        r')';
  }

  static Padding2ByteAlignmentLength6 _structDecode(
      $fidl.Decoder $decoder, int $offset) {
    return Padding2ByteAlignmentLength6(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 2),
        c: $fieldType2.decode($decoder, $offset + 4));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Padding2ByteAlignmentLength6>
    kPadding2ByteAlignmentLength6_Type =
    $fidl.StructType<Padding2ByteAlignmentLength6>(
  inlineSize: 6,
  structDecode: Padding2ByteAlignmentLength6._structDecode,
);

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