// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Code generated by tools/fidl/gidl-conformance-suite/regen.sh; DO NOT EDIT.
// WARNING: This file is machine generated by fidlgen.

library fidl_conformance_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 $zx;

// 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

enum IpAddressConfigTag {
  paddingSize24Align4,
  dhcp,
}

class IpAddressConfig extends $fidl.Union {
  const IpAddressConfig.withPaddingSize24Align4(Uint32List value)
      : _data = value,
        _tag = IpAddressConfigTag.paddingSize24Align4;

  const IpAddressConfig.withDhcp(bool value)
      : _data = value,
        _tag = IpAddressConfigTag.dhcp;

  IpAddressConfig._(IpAddressConfigTag tag, Object data)
      : _tag = tag,
        _data = data;

  final IpAddressConfigTag _tag;
  final _data;
  Uint32List get paddingSize24Align4 {
    if (_tag != IpAddressConfigTag.paddingSize24Align4) {
      return null;
    }
    return _data;
  }

  bool get dhcp {
    if (_tag != IpAddressConfigTag.dhcp) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case IpAddressConfigTag.paddingSize24Align4:
        return r'IpAddressConfig.paddingSize24Align4($paddingSize24Align4)';
      case IpAddressConfigTag.dhcp:
        return r'IpAddressConfig.dhcp($dhcp)';
      default:
        return null;
    }
  }

  IpAddressConfigTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  IpAddressConfigTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static IpAddressConfig _ctor(int index, Object data) {
    return IpAddressConfig._(IpAddressConfigTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<IpAddressConfig> kIpAddressConfig_Type =
    $fidl.UnionType<IpAddressConfig>(
  inlineSizeOld: 28,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Uint32List>(
        type: $fidl.ArrayType<Uint32List>(
            element: $fidl.Uint32Type(), elementCount: 6),
        offsetOld: 4,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<bool>(
        type: $fidl.BoolType(), offsetOld: 4, offsetV1: -1 /* unused */),
  ],
  ctor: IpAddressConfig._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
  },
);

enum UnionWithBoundStringTag {
  boundFiveStr,
}

class UnionWithBoundString extends $fidl.Union {
  const UnionWithBoundString.withBoundFiveStr(String value)
      : _data = value,
        _tag = UnionWithBoundStringTag.boundFiveStr;

  UnionWithBoundString._(UnionWithBoundStringTag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionWithBoundStringTag _tag;
  final _data;
  String get boundFiveStr {
    if (_tag != UnionWithBoundStringTag.boundFiveStr) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionWithBoundStringTag.boundFiveStr:
        return r'UnionWithBoundString.boundFiveStr($boundFiveStr)';
      default:
        return null;
    }
  }

  UnionWithBoundStringTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionWithBoundStringTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionWithBoundString _ctor(int index, Object data) {
    return UnionWithBoundString._(UnionWithBoundStringTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionWithBoundString> kUnionWithBoundString_Type =
    $fidl.UnionType<UnionWithBoundString>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: 5, nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
  ],
  ctor: UnionWithBoundString._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
  },
);

enum SingleVariantUnionTag {
  x,
}

class SingleVariantUnion extends $fidl.Union {
  const SingleVariantUnion.withX(int value)
      : _data = value,
        _tag = SingleVariantUnionTag.x;

  SingleVariantUnion._(SingleVariantUnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final SingleVariantUnionTag _tag;
  final _data;
  int get x {
    if (_tag != SingleVariantUnionTag.x) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case SingleVariantUnionTag.x:
        return r'SingleVariantUnion.x($x)';
      default:
        return null;
    }
  }

  SingleVariantUnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  SingleVariantUnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static SingleVariantUnion _ctor(int index, Object data) {
    return SingleVariantUnion._(SingleVariantUnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<SingleVariantUnion> kSingleVariantUnion_Type =
    $fidl.UnionType<SingleVariantUnion>(
  inlineSizeOld: 8,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 4, offsetV1: -1 /* unused */),
  ],
  ctor: SingleVariantUnion._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
  },
);

enum ReverseOrdinalUnionTag {
  z,
  y,
  x,
}

class ReverseOrdinalUnion extends $fidl.Union {
  const ReverseOrdinalUnion.withZ(int value)
      : _data = value,
        _tag = ReverseOrdinalUnionTag.z;

  const ReverseOrdinalUnion.withY(bool value)
      : _data = value,
        _tag = ReverseOrdinalUnionTag.y;

  const ReverseOrdinalUnion.withX(int value)
      : _data = value,
        _tag = ReverseOrdinalUnionTag.x;

  ReverseOrdinalUnion._(ReverseOrdinalUnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final ReverseOrdinalUnionTag _tag;
  final _data;
  int get z {
    if (_tag != ReverseOrdinalUnionTag.z) {
      return null;
    }
    return _data;
  }

  bool get y {
    if (_tag != ReverseOrdinalUnionTag.y) {
      return null;
    }
    return _data;
  }

  int get x {
    if (_tag != ReverseOrdinalUnionTag.x) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case ReverseOrdinalUnionTag.z:
        return r'ReverseOrdinalUnion.z($z)';
      case ReverseOrdinalUnionTag.y:
        return r'ReverseOrdinalUnion.y($y)';
      case ReverseOrdinalUnionTag.x:
        return r'ReverseOrdinalUnion.x($x)';
      default:
        return null;
    }
  }

  ReverseOrdinalUnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  ReverseOrdinalUnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static ReverseOrdinalUnion _ctor(int index, Object data) {
    return ReverseOrdinalUnion._(ReverseOrdinalUnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ReverseOrdinalUnion> kReverseOrdinalUnion_Type =
    $fidl.UnionType<ReverseOrdinalUnion>(
  inlineSizeOld: 16,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<bool>(
        type: $fidl.BoolType(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Int64Type(), offsetOld: 8, offsetV1: -1 /* unused */),
  ],
  ctor: ReverseOrdinalUnion._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    4: 2,
  },
);

enum UnionWithEmptyStructTag {
  s,
  forceAlignmentOf8,
}

class UnionWithEmptyStruct extends $fidl.Union {
  const UnionWithEmptyStruct.withS(EmptyStruct value)
      : _data = value,
        _tag = UnionWithEmptyStructTag.s;

  const UnionWithEmptyStruct.withForceAlignmentOf8(int value)
      : _data = value,
        _tag = UnionWithEmptyStructTag.forceAlignmentOf8;

  UnionWithEmptyStruct._(UnionWithEmptyStructTag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionWithEmptyStructTag _tag;
  final _data;
  EmptyStruct get s {
    if (_tag != UnionWithEmptyStructTag.s) {
      return null;
    }
    return _data;
  }

  int get forceAlignmentOf8 {
    if (_tag != UnionWithEmptyStructTag.forceAlignmentOf8) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionWithEmptyStructTag.s:
        return r'UnionWithEmptyStruct.s($s)';
      case UnionWithEmptyStructTag.forceAlignmentOf8:
        return r'UnionWithEmptyStruct.forceAlignmentOf8($forceAlignmentOf8)';
      default:
        return null;
    }
  }

  UnionWithEmptyStructTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionWithEmptyStructTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionWithEmptyStruct _ctor(int index, Object data) {
    return UnionWithEmptyStruct._(UnionWithEmptyStructTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionWithEmptyStruct> kUnionWithEmptyStruct_Type =
    $fidl.UnionType<UnionWithEmptyStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<EmptyStruct>(
        type: kEmptyStruct_Type, offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 8, offsetV1: -1 /* unused */),
  ],
  ctor: UnionWithEmptyStruct._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
  },
);

enum UnionSize8Align4Tag {
  unused1,
  unused2,
  variant,
}

class UnionSize8Align4 extends $fidl.Union {
  const UnionSize8Align4.withUnused1(int value)
      : _data = value,
        _tag = UnionSize8Align4Tag.unused1;

  const UnionSize8Align4.withUnused2(int value)
      : _data = value,
        _tag = UnionSize8Align4Tag.unused2;

  const UnionSize8Align4.withVariant(int value)
      : _data = value,
        _tag = UnionSize8Align4Tag.variant;

  UnionSize8Align4._(UnionSize8Align4Tag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionSize8Align4Tag _tag;
  final _data;
  int get unused1 {
    if (_tag != UnionSize8Align4Tag.unused1) {
      return null;
    }
    return _data;
  }

  int get unused2 {
    if (_tag != UnionSize8Align4Tag.unused2) {
      return null;
    }
    return _data;
  }

  int get variant {
    if (_tag != UnionSize8Align4Tag.variant) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionSize8Align4Tag.unused1:
        return r'UnionSize8Align4.unused1($unused1)';
      case UnionSize8Align4Tag.unused2:
        return r'UnionSize8Align4.unused2($unused2)';
      case UnionSize8Align4Tag.variant:
        return r'UnionSize8Align4.variant($variant)';
      default:
        return null;
    }
  }

  UnionSize8Align4Tag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionSize8Align4Tag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionSize8Align4 _ctor(int index, Object data) {
    return UnionSize8Align4._(UnionSize8Align4Tag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionSize8Align4> kUnionSize8Align4_Type =
    $fidl.UnionType<UnionSize8Align4>(
  inlineSizeOld: 8,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 4, offsetV1: -1 /* unused */),
  ],
  ctor: UnionSize8Align4._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
  },
);

enum UnionSize12Align4Tag {
  unused1,
  unused2,
  unused3,
  variant,
}

class UnionSize12Align4 extends $fidl.Union {
  const UnionSize12Align4.withUnused1(int value)
      : _data = value,
        _tag = UnionSize12Align4Tag.unused1;

  const UnionSize12Align4.withUnused2(int value)
      : _data = value,
        _tag = UnionSize12Align4Tag.unused2;

  const UnionSize12Align4.withUnused3(int value)
      : _data = value,
        _tag = UnionSize12Align4Tag.unused3;

  const UnionSize12Align4.withVariant(Uint8List value)
      : _data = value,
        _tag = UnionSize12Align4Tag.variant;

  UnionSize12Align4._(UnionSize12Align4Tag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionSize12Align4Tag _tag;
  final _data;
  int get unused1 {
    if (_tag != UnionSize12Align4Tag.unused1) {
      return null;
    }
    return _data;
  }

  int get unused2 {
    if (_tag != UnionSize12Align4Tag.unused2) {
      return null;
    }
    return _data;
  }

  int get unused3 {
    if (_tag != UnionSize12Align4Tag.unused3) {
      return null;
    }
    return _data;
  }

  Uint8List get variant {
    if (_tag != UnionSize12Align4Tag.variant) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionSize12Align4Tag.unused1:
        return r'UnionSize12Align4.unused1($unused1)';
      case UnionSize12Align4Tag.unused2:
        return r'UnionSize12Align4.unused2($unused2)';
      case UnionSize12Align4Tag.unused3:
        return r'UnionSize12Align4.unused3($unused3)';
      case UnionSize12Align4Tag.variant:
        return r'UnionSize12Align4.variant($variant)';
      default:
        return null;
    }
  }

  UnionSize12Align4Tag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionSize12Align4Tag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionSize12Align4 _ctor(int index, Object data) {
    return UnionSize12Align4._(UnionSize12Align4Tag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionSize12Align4> kUnionSize12Align4_Type =
    $fidl.UnionType<UnionSize12Align4>(
  inlineSizeOld: 12,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<Uint8List>(
        type: $fidl.ArrayType<Uint8List>(
            element: $fidl.Uint8Type(), elementCount: 6),
        offsetOld: 4,
        offsetV1: -1 /* unused */),
  ],
  ctor: UnionSize12Align4._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
    4: 3,
  },
);

enum UnionSize24Align8Tag {
  unused1,
  unused2,
  unused3,
  variant,
}

class UnionSize24Align8 extends $fidl.Union {
  const UnionSize24Align8.withUnused1(int value)
      : _data = value,
        _tag = UnionSize24Align8Tag.unused1;

  const UnionSize24Align8.withUnused2(int value)
      : _data = value,
        _tag = UnionSize24Align8Tag.unused2;

  const UnionSize24Align8.withUnused3(int value)
      : _data = value,
        _tag = UnionSize24Align8Tag.unused3;

  const UnionSize24Align8.withVariant(StructSize16Align8 value)
      : _data = value,
        _tag = UnionSize24Align8Tag.variant;

  UnionSize24Align8._(UnionSize24Align8Tag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionSize24Align8Tag _tag;
  final _data;
  int get unused1 {
    if (_tag != UnionSize24Align8Tag.unused1) {
      return null;
    }
    return _data;
  }

  int get unused2 {
    if (_tag != UnionSize24Align8Tag.unused2) {
      return null;
    }
    return _data;
  }

  int get unused3 {
    if (_tag != UnionSize24Align8Tag.unused3) {
      return null;
    }
    return _data;
  }

  StructSize16Align8 get variant {
    if (_tag != UnionSize24Align8Tag.variant) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionSize24Align8Tag.unused1:
        return r'UnionSize24Align8.unused1($unused1)';
      case UnionSize24Align8Tag.unused2:
        return r'UnionSize24Align8.unused2($unused2)';
      case UnionSize24Align8Tag.unused3:
        return r'UnionSize24Align8.unused3($unused3)';
      case UnionSize24Align8Tag.variant:
        return r'UnionSize24Align8.variant($variant)';
      default:
        return null;
    }
  }

  UnionSize24Align8Tag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionSize24Align8Tag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionSize24Align8 _ctor(int index, Object data) {
    return UnionSize24Align8._(UnionSize24Align8Tag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionSize24Align8> kUnionSize24Align8_Type =
    $fidl.UnionType<UnionSize24Align8>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<StructSize16Align8>(
        type: kStructSize16Align8_Type,
        offsetOld: 8,
        offsetV1: -1 /* unused */),
  ],
  ctor: UnionSize24Align8._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
    4: 3,
  },
);

enum UnionSize36Align4Tag {
  unused1,
  unused2,
  unused3,
  variant,
}

class UnionSize36Align4 extends $fidl.Union {
  const UnionSize36Align4.withUnused1(int value)
      : _data = value,
        _tag = UnionSize36Align4Tag.unused1;

  const UnionSize36Align4.withUnused2(int value)
      : _data = value,
        _tag = UnionSize36Align4Tag.unused2;

  const UnionSize36Align4.withUnused3(int value)
      : _data = value,
        _tag = UnionSize36Align4Tag.unused3;

  const UnionSize36Align4.withVariant(Uint8List value)
      : _data = value,
        _tag = UnionSize36Align4Tag.variant;

  UnionSize36Align4._(UnionSize36Align4Tag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionSize36Align4Tag _tag;
  final _data;
  int get unused1 {
    if (_tag != UnionSize36Align4Tag.unused1) {
      return null;
    }
    return _data;
  }

  int get unused2 {
    if (_tag != UnionSize36Align4Tag.unused2) {
      return null;
    }
    return _data;
  }

  int get unused3 {
    if (_tag != UnionSize36Align4Tag.unused3) {
      return null;
    }
    return _data;
  }

  Uint8List get variant {
    if (_tag != UnionSize36Align4Tag.variant) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionSize36Align4Tag.unused1:
        return r'UnionSize36Align4.unused1($unused1)';
      case UnionSize36Align4Tag.unused2:
        return r'UnionSize36Align4.unused2($unused2)';
      case UnionSize36Align4Tag.unused3:
        return r'UnionSize36Align4.unused3($unused3)';
      case UnionSize36Align4Tag.variant:
        return r'UnionSize36Align4.variant($variant)';
      default:
        return null;
    }
  }

  UnionSize36Align4Tag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionSize36Align4Tag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionSize36Align4 _ctor(int index, Object data) {
    return UnionSize36Align4._(UnionSize36Align4Tag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionSize36Align4> kUnionSize36Align4_Type =
    $fidl.UnionType<UnionSize36Align4>(
  inlineSizeOld: 36,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<Uint8List>(
        type: $fidl.ArrayType<Uint8List>(
            element: $fidl.Uint8Type(), elementCount: 32),
        offsetOld: 4,
        offsetV1: -1 /* unused */),
  ],
  ctor: UnionSize36Align4._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
    4: 3,
  },
);

enum UnionOfUnionTag {
  unused1,
  size8align4,
  size12align4,
  unused2,
  size24align8,
}

class UnionOfUnion extends $fidl.Union {
  const UnionOfUnion.withUnused1(int value)
      : _data = value,
        _tag = UnionOfUnionTag.unused1;

  const UnionOfUnion.withSize8align4(UnionSize8Align4 value)
      : _data = value,
        _tag = UnionOfUnionTag.size8align4;

  const UnionOfUnion.withSize12align4(UnionSize12Align4 value)
      : _data = value,
        _tag = UnionOfUnionTag.size12align4;

  const UnionOfUnion.withUnused2(int value)
      : _data = value,
        _tag = UnionOfUnionTag.unused2;

  const UnionOfUnion.withSize24align8(UnionSize24Align8 value)
      : _data = value,
        _tag = UnionOfUnionTag.size24align8;

  UnionOfUnion._(UnionOfUnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionOfUnionTag _tag;
  final _data;
  int get unused1 {
    if (_tag != UnionOfUnionTag.unused1) {
      return null;
    }
    return _data;
  }

  UnionSize8Align4 get size8align4 {
    if (_tag != UnionOfUnionTag.size8align4) {
      return null;
    }
    return _data;
  }

  UnionSize12Align4 get size12align4 {
    if (_tag != UnionOfUnionTag.size12align4) {
      return null;
    }
    return _data;
  }

  int get unused2 {
    if (_tag != UnionOfUnionTag.unused2) {
      return null;
    }
    return _data;
  }

  UnionSize24Align8 get size24align8 {
    if (_tag != UnionOfUnionTag.size24align8) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionOfUnionTag.unused1:
        return r'UnionOfUnion.unused1($unused1)';
      case UnionOfUnionTag.size8align4:
        return r'UnionOfUnion.size8align4($size8align4)';
      case UnionOfUnionTag.size12align4:
        return r'UnionOfUnion.size12align4($size12align4)';
      case UnionOfUnionTag.unused2:
        return r'UnionOfUnion.unused2($unused2)';
      case UnionOfUnionTag.size24align8:
        return r'UnionOfUnion.size24align8($size24align8)';
      default:
        return null;
    }
  }

  UnionOfUnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionOfUnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionOfUnion _ctor(int index, Object data) {
    return UnionOfUnion._(UnionOfUnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionOfUnion> kUnionOfUnion_Type =
    $fidl.UnionType<UnionOfUnion>(
  inlineSizeOld: 32,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<UnionSize8Align4>(
        type: kUnionSize8Align4_Type, offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<UnionSize12Align4>(
        type: kUnionSize12Align4_Type, offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<UnionSize24Align8>(
        type: kUnionSize24Align8_Type, offsetOld: 8, offsetV1: -1 /* unused */),
  ],
  ctor: UnionOfUnion._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
    4: 3,
    5: 4,
  },
);

enum UnionWithVectorTag {
  unused,
  vectorOfUint8,
  s,
  vectorS3A1,
  vectorS3A2,
  handles,
  arrayS3A1,
  arrayS3A2,
  vectorUnion,
}

class UnionWithVector extends $fidl.Union {
  const UnionWithVector.withUnused(int value)
      : _data = value,
        _tag = UnionWithVectorTag.unused;

  const UnionWithVector.withVectorOfUint8(Uint8List value)
      : _data = value,
        _tag = UnionWithVectorTag.vectorOfUint8;

  const UnionWithVector.withS(String value)
      : _data = value,
        _tag = UnionWithVectorTag.s;

  const UnionWithVector.withVectorS3A1(List<StructSize3Align1> value)
      : _data = value,
        _tag = UnionWithVectorTag.vectorS3A1;

  const UnionWithVector.withVectorS3A2(List<StructSize3Align2> value)
      : _data = value,
        _tag = UnionWithVectorTag.vectorS3A2;

  const UnionWithVector.withHandles(Uint32List value)
      : _data = value,
        _tag = UnionWithVectorTag.handles;

  const UnionWithVector.withArrayS3A1(List<StructSize3Align1> value)
      : _data = value,
        _tag = UnionWithVectorTag.arrayS3A1;

  const UnionWithVector.withArrayS3A2(List<StructSize3Align2> value)
      : _data = value,
        _tag = UnionWithVectorTag.arrayS3A2;

  const UnionWithVector.withVectorUnion(List<UnionSize8Align4> value)
      : _data = value,
        _tag = UnionWithVectorTag.vectorUnion;

  UnionWithVector._(UnionWithVectorTag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionWithVectorTag _tag;
  final _data;
  int get unused {
    if (_tag != UnionWithVectorTag.unused) {
      return null;
    }
    return _data;
  }

  Uint8List get vectorOfUint8 {
    if (_tag != UnionWithVectorTag.vectorOfUint8) {
      return null;
    }
    return _data;
  }

  String get s {
    if (_tag != UnionWithVectorTag.s) {
      return null;
    }
    return _data;
  }

  List<StructSize3Align1> get vectorS3A1 {
    if (_tag != UnionWithVectorTag.vectorS3A1) {
      return null;
    }
    return _data;
  }

  List<StructSize3Align2> get vectorS3A2 {
    if (_tag != UnionWithVectorTag.vectorS3A2) {
      return null;
    }
    return _data;
  }

  Uint32List get handles {
    if (_tag != UnionWithVectorTag.handles) {
      return null;
    }
    return _data;
  }

  List<StructSize3Align1> get arrayS3A1 {
    if (_tag != UnionWithVectorTag.arrayS3A1) {
      return null;
    }
    return _data;
  }

  List<StructSize3Align2> get arrayS3A2 {
    if (_tag != UnionWithVectorTag.arrayS3A2) {
      return null;
    }
    return _data;
  }

  List<UnionSize8Align4> get vectorUnion {
    if (_tag != UnionWithVectorTag.vectorUnion) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionWithVectorTag.unused:
        return r'UnionWithVector.unused($unused)';
      case UnionWithVectorTag.vectorOfUint8:
        return r'UnionWithVector.vectorOfUint8($vectorOfUint8)';
      case UnionWithVectorTag.s:
        return r'UnionWithVector.s($s)';
      case UnionWithVectorTag.vectorS3A1:
        return r'UnionWithVector.vectorS3A1($vectorS3A1)';
      case UnionWithVectorTag.vectorS3A2:
        return r'UnionWithVector.vectorS3A2($vectorS3A2)';
      case UnionWithVectorTag.handles:
        return r'UnionWithVector.handles($handles)';
      case UnionWithVectorTag.arrayS3A1:
        return r'UnionWithVector.arrayS3A1($arrayS3A1)';
      case UnionWithVectorTag.arrayS3A2:
        return r'UnionWithVector.arrayS3A2($arrayS3A2)';
      case UnionWithVectorTag.vectorUnion:
        return r'UnionWithVector.vectorUnion($vectorUnion)';
      default:
        return null;
    }
  }

  UnionWithVectorTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionWithVectorTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionWithVector _ctor(int index, Object data) {
    return UnionWithVector._(UnionWithVectorTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionWithVector> kUnionWithVector_Type =
    $fidl.UnionType<UnionWithVector>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<Uint8List>(
        type: $fidl.VectorType<Uint8List>(
            element: $fidl.Uint8Type(),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<List<StructSize3Align1>>(
        type: $fidl.VectorType<List<StructSize3Align1>>(
            element: kStructSize3Align1_Type,
            maybeElementCount: null,
            nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<List<StructSize3Align2>>(
        type: $fidl.VectorType<List<StructSize3Align2>>(
            element: kStructSize3Align2_Type,
            maybeElementCount: null,
            nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<Uint32List>(
        type: $fidl.VectorType<Uint32List>(
            element: $fidl.Uint32Type(),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<List<StructSize3Align1>>(
        type: $fidl.ArrayType<List<StructSize3Align1>>(
            element: kStructSize3Align1_Type, elementCount: 2),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<List<StructSize3Align2>>(
        type: $fidl.ArrayType<List<StructSize3Align2>>(
            element: kStructSize3Align2_Type, elementCount: 2),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<List<UnionSize8Align4>>(
        type: $fidl.VectorType<List<UnionSize8Align4>>(
            element: kUnionSize8Align4_Type,
            maybeElementCount: null,
            nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
  ],
  ctor: UnionWithVector._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
    4: 3,
    5: 4,
    6: 5,
    7: 6,
    8: 7,
    9: 8,
  },
);

enum StringUnionTag {
  unused,
  s,
  u8,
}

class StringUnion extends $fidl.Union {
  const StringUnion.withUnused(int value)
      : _data = value,
        _tag = StringUnionTag.unused;

  const StringUnion.withS(String value)
      : _data = value,
        _tag = StringUnionTag.s;

  const StringUnion.withU8(int value)
      : _data = value,
        _tag = StringUnionTag.u8;

  StringUnion._(StringUnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final StringUnionTag _tag;
  final _data;
  int get unused {
    if (_tag != StringUnionTag.unused) {
      return null;
    }
    return _data;
  }

  String get s {
    if (_tag != StringUnionTag.s) {
      return null;
    }
    return _data;
  }

  int get u8 {
    if (_tag != StringUnionTag.u8) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case StringUnionTag.unused:
        return r'StringUnion.unused($unused)';
      case StringUnionTag.s:
        return r'StringUnion.s($s)';
      case StringUnionTag.u8:
        return r'StringUnion.u8($u8)';
      default:
        return null;
    }
  }

  StringUnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  StringUnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static StringUnion _ctor(int index, Object data) {
    return StringUnion._(StringUnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StringUnion> kStringUnion_Type =
    $fidl.UnionType<StringUnion>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: -1 /* unused */),
  ],
  ctor: StringUnion._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
  },
);

enum EmptyStructUnionTag {
  unused,
  es,
}

class EmptyStructUnion extends $fidl.Union {
  const EmptyStructUnion.withUnused(int value)
      : _data = value,
        _tag = EmptyStructUnionTag.unused;

  const EmptyStructUnion.withEs(TransformerEmptyStruct value)
      : _data = value,
        _tag = EmptyStructUnionTag.es;

  EmptyStructUnion._(EmptyStructUnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final EmptyStructUnionTag _tag;
  final _data;
  int get unused {
    if (_tag != EmptyStructUnionTag.unused) {
      return null;
    }
    return _data;
  }

  TransformerEmptyStruct get es {
    if (_tag != EmptyStructUnionTag.es) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case EmptyStructUnionTag.unused:
        return r'EmptyStructUnion.unused($unused)';
      case EmptyStructUnionTag.es:
        return r'EmptyStructUnion.es($es)';
      default:
        return null;
    }
  }

  EmptyStructUnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  EmptyStructUnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static EmptyStructUnion _ctor(int index, Object data) {
    return EmptyStructUnion._(EmptyStructUnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<EmptyStructUnion> kEmptyStructUnion_Type =
    $fidl.UnionType<EmptyStructUnion>(
  inlineSizeOld: 8,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: -1 /* unused */),
    $fidl.MemberType<TransformerEmptyStruct>(
        type: kTransformerEmptyStruct_Type,
        offsetOld: 4,
        offsetV1: -1 /* unused */),
  ],
  ctor: EmptyStructUnion._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
  },
);

enum UnionWithVectorOfVectorsTag {
  v,
}

class UnionWithVectorOfVectors extends $fidl.Union {
  const UnionWithVectorOfVectors.withV(List<List<StructSize3Align1>> value)
      : _data = value,
        _tag = UnionWithVectorOfVectorsTag.v;

  UnionWithVectorOfVectors._(UnionWithVectorOfVectorsTag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionWithVectorOfVectorsTag _tag;
  final _data;
  List<List<StructSize3Align1>> get v {
    if (_tag != UnionWithVectorOfVectorsTag.v) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionWithVectorOfVectorsTag.v:
        return r'UnionWithVectorOfVectors.v($v)';
      default:
        return null;
    }
  }

  UnionWithVectorOfVectorsTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionWithVectorOfVectorsTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static UnionWithVectorOfVectors _ctor(int index, Object data) {
    return UnionWithVectorOfVectors._(
        UnionWithVectorOfVectorsTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<UnionWithVectorOfVectors> kUnionWithVectorOfVectors_Type =
    $fidl.UnionType<UnionWithVectorOfVectors>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<List<StructSize3Align1>>>(
        type: $fidl.VectorType<List<List<StructSize3Align1>>>(
            element: $fidl.VectorType<List<StructSize3Align1>>(
                element: $fidl.PointerType<StructSize3Align1>(
                    element: kStructSize3Align1_Type),
                maybeElementCount: null,
                nullable: false),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
  ],
  ctor: UnionWithVectorOfVectors._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
  },
);

enum SimpleUnionTag {
  i32,
  i64,
  s,
  str,
}

class SimpleUnion extends $fidl.Union {
  const SimpleUnion.withI32(int value)
      : _data = value,
        _tag = SimpleUnionTag.i32;

  const SimpleUnion.withI64(int value)
      : _data = value,
        _tag = SimpleUnionTag.i64;

  const SimpleUnion.withS(Int64Struct value)
      : _data = value,
        _tag = SimpleUnionTag.s;

  const SimpleUnion.withStr(String value)
      : _data = value,
        _tag = SimpleUnionTag.str;

  SimpleUnion._(SimpleUnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final SimpleUnionTag _tag;
  final _data;
  int get i32 {
    if (_tag != SimpleUnionTag.i32) {
      return null;
    }
    return _data;
  }

  int get i64 {
    if (_tag != SimpleUnionTag.i64) {
      return null;
    }
    return _data;
  }

  Int64Struct get s {
    if (_tag != SimpleUnionTag.s) {
      return null;
    }
    return _data;
  }

  String get str {
    if (_tag != SimpleUnionTag.str) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case SimpleUnionTag.i32:
        return r'SimpleUnion.i32($i32)';
      case SimpleUnionTag.i64:
        return r'SimpleUnion.i64($i64)';
      case SimpleUnionTag.s:
        return r'SimpleUnion.s($s)';
      case SimpleUnionTag.str:
        return r'SimpleUnion.str($str)';
      default:
        return null;
    }
  }

  SimpleUnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  SimpleUnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static SimpleUnion _ctor(int index, Object data) {
    return SimpleUnion._(SimpleUnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<SimpleUnion> kSimpleUnion_Type =
    $fidl.UnionType<SimpleUnion>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(
        type: $fidl.Int32Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<int>(
        type: $fidl.Int64Type(), offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<Int64Struct>(
        type: kInt64Struct_Type, offsetOld: 8, offsetV1: -1 /* unused */),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 8,
        offsetV1: -1 /* unused */),
  ],
  ctor: SimpleUnion._ctor,
  ordinalToIndex: <int, int>{
    1: 0,
    2: 1,
    3: 2,
    4: 3,
  },
);

enum XUnionWithEmptyStructTag {
  $unknown,
  s, // 0x7499e0fe
}

const Map<int, XUnionWithEmptyStructTag> _XUnionWithEmptyStructTag_map = {
  1956241662: XUnionWithEmptyStructTag.s,
};

class XUnionWithEmptyStruct extends $fidl.XUnion {
  const XUnionWithEmptyStruct.withS(EmptyStruct value)
      : _ordinal = 1956241662,
        _data = value;

  XUnionWithEmptyStruct._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  XUnionWithEmptyStructTag get $tag {
    final XUnionWithEmptyStructTag $rawtag =
        _XUnionWithEmptyStructTag_map[_ordinal];
    return $rawtag == null ? XUnionWithEmptyStructTag.$unknown : $rawtag;
  }

  EmptyStruct get s {
    if (_ordinal != 1956241662) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1956241662:
        return 'XUnionWithEmptyStruct.s($s)';
      default:
        return 'XUnionWithEmptyStruct.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static XUnionWithEmptyStruct _ctor(int ordinal, Object data) {
    return XUnionWithEmptyStruct._(ordinal, data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithEmptyStruct> kXUnionWithEmptyStruct_Type =
    $fidl.XUnionType<XUnionWithEmptyStruct>(
  members: <int, $fidl.FidlType>{
    1956241662: kEmptyStruct_Type,
  },
  ctor: XUnionWithEmptyStruct._ctor,
  nullable: false,
  flexible: true,
);
// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithEmptyStruct> kXUnionWithEmptyStruct_OptType =
    $fidl.XUnionType<XUnionWithEmptyStruct>(
  members: <int, $fidl.FidlType>{
    1956241662: kEmptyStruct_Type,
  },
  ctor: XUnionWithEmptyStruct._ctor,
  nullable: true,
  flexible: true,
);

enum XUnionWithStructTag {
  $unknown,
  s, // 0x193e5c14
}

const Map<int, XUnionWithStructTag> _XUnionWithStructTag_map = {
  423517204: XUnionWithStructTag.s,
};

class XUnionWithStruct extends $fidl.XUnion {
  const XUnionWithStruct.withS(StructSize3Align1 value)
      : _ordinal = 423517204,
        _data = value;

  XUnionWithStruct._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  XUnionWithStructTag get $tag {
    final XUnionWithStructTag $rawtag = _XUnionWithStructTag_map[_ordinal];
    return $rawtag == null ? XUnionWithStructTag.$unknown : $rawtag;
  }

  StructSize3Align1 get s {
    if (_ordinal != 423517204) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 423517204:
        return 'XUnionWithStruct.s($s)';
      default:
        return 'XUnionWithStruct.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static XUnionWithStruct _ctor(int ordinal, Object data) {
    return XUnionWithStruct._(ordinal, data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithStruct> kXUnionWithStruct_Type =
    $fidl.XUnionType<XUnionWithStruct>(
  members: <int, $fidl.FidlType>{
    423517204: kStructSize3Align1_Type,
  },
  ctor: XUnionWithStruct._ctor,
  nullable: false,
  flexible: true,
);
// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithStruct> kXUnionWithStruct_OptType =
    $fidl.XUnionType<XUnionWithStruct>(
  members: <int, $fidl.FidlType>{
    423517204: kStructSize3Align1_Type,
  },
  ctor: XUnionWithStruct._ctor,
  nullable: true,
  flexible: true,
);

enum XUnionWithXUnionTag {
  $unknown,
  xu, // 0x6c06691f
}

const Map<int, XUnionWithXUnionTag> _XUnionWithXUnionTag_map = {
  1812359455: XUnionWithXUnionTag.xu,
};

class XUnionWithXUnion extends $fidl.XUnion {
  const XUnionWithXUnion.withXu(XUnionWithStruct value)
      : _ordinal = 1812359455,
        _data = value;

  XUnionWithXUnion._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  XUnionWithXUnionTag get $tag {
    final XUnionWithXUnionTag $rawtag = _XUnionWithXUnionTag_map[_ordinal];
    return $rawtag == null ? XUnionWithXUnionTag.$unknown : $rawtag;
  }

  XUnionWithStruct get xu {
    if (_ordinal != 1812359455) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1812359455:
        return 'XUnionWithXUnion.xu($xu)';
      default:
        return 'XUnionWithXUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static XUnionWithXUnion _ctor(int ordinal, Object data) {
    return XUnionWithXUnion._(ordinal, data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithXUnion> kXUnionWithXUnion_Type =
    $fidl.XUnionType<XUnionWithXUnion>(
  members: <int, $fidl.FidlType>{
    1812359455: kXUnionWithStruct_Type,
  },
  ctor: XUnionWithXUnion._ctor,
  nullable: false,
  flexible: true,
);
// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithXUnion> kXUnionWithXUnion_OptType =
    $fidl.XUnionType<XUnionWithXUnion>(
  members: <int, $fidl.FidlType>{
    1812359455: kXUnionWithStruct_Type,
  },
  ctor: XUnionWithXUnion._ctor,
  nullable: true,
  flexible: true,
);

enum XUnionWithUnionsTag {
  $unknown,
  u1, // 0x28c52917
  u2, // 0x75862b98
}

const Map<int, XUnionWithUnionsTag> _XUnionWithUnionsTag_map = {
  684009751: XUnionWithUnionsTag.u1,
  1971727256: XUnionWithUnionsTag.u2,
};

class XUnionWithUnions extends $fidl.XUnion {
  const XUnionWithUnions.withU1(UnionSize8Align4 value)
      : _ordinal = 684009751,
        _data = value;

  const XUnionWithUnions.withU2(UnionSize12Align4 value)
      : _ordinal = 1971727256,
        _data = value;

  XUnionWithUnions._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  XUnionWithUnionsTag get $tag {
    final XUnionWithUnionsTag $rawtag = _XUnionWithUnionsTag_map[_ordinal];
    return $rawtag == null ? XUnionWithUnionsTag.$unknown : $rawtag;
  }

  UnionSize8Align4 get u1 {
    if (_ordinal != 684009751) {
      return null;
    }
    return _data;
  }

  UnionSize12Align4 get u2 {
    if (_ordinal != 1971727256) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 684009751:
        return 'XUnionWithUnions.u1($u1)';
      case 1971727256:
        return 'XUnionWithUnions.u2($u2)';
      default:
        return 'XUnionWithUnions.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static XUnionWithUnions _ctor(int ordinal, Object data) {
    return XUnionWithUnions._(ordinal, data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithUnions> kXUnionWithUnions_Type =
    $fidl.XUnionType<XUnionWithUnions>(
  members: <int, $fidl.FidlType>{
    684009751: kUnionSize8Align4_Type,
    1971727256: kUnionSize12Align4_Type,
  },
  ctor: XUnionWithUnions._ctor,
  nullable: false,
  flexible: true,
);
// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<XUnionWithUnions> kXUnionWithUnions_OptType =
    $fidl.XUnionType<XUnionWithUnions>(
  members: <int, $fidl.FidlType>{
    684009751: kUnionSize8Align4_Type,
    1971727256: kUnionSize12Align4_Type,
  },
  ctor: XUnionWithUnions._ctor,
  nullable: true,
  flexible: true,
);

enum SampleXUnionTag {
  $unknown,
  u, // 0x389c56b2
  su, // 0x792f4f1d
  st, // 0x21de8d5
}

const Map<int, SampleXUnionTag> _SampleXUnionTag_map = {
  949769906: SampleXUnionTag.u,
  2033143581: SampleXUnionTag.su,
  35514581: SampleXUnionTag.st,
};

class SampleXUnion extends $fidl.XUnion {
  const SampleXUnion.withU(int value)
      : _ordinal = 949769906,
        _data = value;

  const SampleXUnion.withSu(SimpleUnion value)
      : _ordinal = 2033143581,
        _data = value;

  const SampleXUnion.withSt(SimpleTable value)
      : _ordinal = 35514581,
        _data = value;

  SampleXUnion._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  SampleXUnionTag get $tag {
    final SampleXUnionTag $rawtag = _SampleXUnionTag_map[_ordinal];
    return $rawtag == null ? SampleXUnionTag.$unknown : $rawtag;
  }

  int get u {
    if (_ordinal != 949769906) {
      return null;
    }
    return _data;
  }

  SimpleUnion get su {
    if (_ordinal != 2033143581) {
      return null;
    }
    return _data;
  }

  SimpleTable get st {
    if (_ordinal != 35514581) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 949769906:
        return 'SampleXUnion.u($u)';
      case 2033143581:
        return 'SampleXUnion.su($su)';
      case 35514581:
        return 'SampleXUnion.st($st)';
      default:
        return 'SampleXUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static SampleXUnion _ctor(int ordinal, Object data) {
    return SampleXUnion._(ordinal, data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<SampleXUnion> kSampleXUnion_Type =
    $fidl.XUnionType<SampleXUnion>(
  members: <int, $fidl.FidlType>{
    949769906: $fidl.Uint32Type(),
    2033143581: kSimpleUnion_Type,
    35514581: kSimpleTable_Type,
  },
  ctor: SampleXUnion._ctor,
  nullable: false,
  flexible: true,
);
// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<SampleXUnion> kSampleXUnion_OptType =
    $fidl.XUnionType<SampleXUnion>(
  members: <int, $fidl.FidlType>{
    949769906: $fidl.Uint32Type(),
    2033143581: kSimpleUnion_Type,
    35514581: kSimpleTable_Type,
  },
  ctor: SampleXUnion._ctor,
  nullable: true,
  flexible: true,
);

enum SampleStrictXUnionTag {
  u, // 0x8e2ea72
  su, // 0x27f3a73b
  st, // 0x372354ef
}

const Map<int, SampleStrictXUnionTag> _SampleStrictXUnionTag_map = {
  149088882: SampleStrictXUnionTag.u,
  670279483: SampleStrictXUnionTag.su,
  925062383: SampleStrictXUnionTag.st,
};

class SampleStrictXUnion extends $fidl.XUnion {
  const SampleStrictXUnion.withU(int value)
      : _ordinal = 149088882,
        _data = value;

  const SampleStrictXUnion.withSu(SimpleUnion value)
      : _ordinal = 670279483,
        _data = value;

  const SampleStrictXUnion.withSt(SimpleTable value)
      : _ordinal = 925062383,
        _data = value;

  SampleStrictXUnion._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  SampleStrictXUnionTag get $tag => _SampleStrictXUnionTag_map[_ordinal];

  int get u {
    if (_ordinal != 149088882) {
      return null;
    }
    return _data;
  }

  SimpleUnion get su {
    if (_ordinal != 670279483) {
      return null;
    }
    return _data;
  }

  SimpleTable get st {
    if (_ordinal != 925062383) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 149088882:
        return 'SampleStrictXUnion.u($u)';
      case 670279483:
        return 'SampleStrictXUnion.su($su)';
      case 925062383:
        return 'SampleStrictXUnion.st($st)';
      default:
        return null;
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static SampleStrictXUnion _ctor(int ordinal, Object data) {
    return SampleStrictXUnion._(ordinal, data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<SampleStrictXUnion> kSampleStrictXUnion_Type =
    $fidl.XUnionType<SampleStrictXUnion>(
  members: <int, $fidl.FidlType>{
    149088882: $fidl.Uint32Type(),
    670279483: kSimpleUnion_Type,
    925062383: kSimpleTable_Type,
  },
  ctor: SampleStrictXUnion._ctor,
  nullable: false,
  flexible: false,
);
// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<SampleStrictXUnion> kSampleStrictXUnion_OptType =
    $fidl.XUnionType<SampleStrictXUnion>(
  members: <int, $fidl.FidlType>{
    149088882: $fidl.Uint32Type(),
    670279483: kSimpleUnion_Type,
    925062383: kSimpleTable_Type,
  },
  ctor: SampleStrictXUnion._ctor,
  nullable: true,
  flexible: false,
);

class TestXUnionInTable extends $fidl.Struct {
  const TestXUnionInTable({
    @required this.value,
  });
  TestXUnionInTable.clone(
    TestXUnionInTable $orig, {
    XUnionInTable value,
  }) : this(
          value: value ?? $orig.value,
        );

  TestXUnionInTable._(List<Object> argv) : value = argv[0];
  final XUnionInTable value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TestXUnionInTable' r'(value: ' + value.toString() + r')';
  }

  static TestXUnionInTable _ctor(List<Object> argv) =>
      TestXUnionInTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TestXUnionInTable> kTestXUnionInTable_Type =
    $fidl.StructType<TestXUnionInTable>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<XUnionInTable>(
        type: kXUnionInTable_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: TestXUnionInTable._ctor,
);

class InterfaceConfig extends $fidl.Struct {
  const InterfaceConfig({
    @required this.name,
    @required this.ipAddressConfig,
  });
  InterfaceConfig.clone(
    InterfaceConfig $orig, {
    String name,
    IpAddressConfig ipAddressConfig,
  }) : this(
          name: name ?? $orig.name,
          ipAddressConfig: ipAddressConfig ?? $orig.ipAddressConfig,
        );

  InterfaceConfig._(List<Object> argv)
      : name = argv[0],
        ipAddressConfig = argv[1];
  final String name;
  final IpAddressConfig ipAddressConfig;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'InterfaceConfig' r'(name: ' +
        name.toString() +
        r', ipAddressConfig: ' +
        ipAddressConfig.toString() +
        r')';
  }

  static InterfaceConfig _ctor(List<Object> argv) => InterfaceConfig._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<InterfaceConfig> kInterfaceConfig_Type =
    $fidl.StructType<InterfaceConfig>(
  inlineSizeOld: 48,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<IpAddressConfig>(
        type: kIpAddressConfig_Type, offsetOld: 16, offsetV1: 16),
  ],
  ctor: InterfaceConfig._ctor,
);

class TestAddEthernetDeviceRequest extends $fidl.Struct {
  const TestAddEthernetDeviceRequest({
    @required this.topologicalPath,
    @required this.config,
    @required this.thisShouldBeAHandle,
  });
  TestAddEthernetDeviceRequest.clone(
    TestAddEthernetDeviceRequest $orig, {
    String topologicalPath,
    InterfaceConfig config,
    int thisShouldBeAHandle,
  }) : this(
          topologicalPath: topologicalPath ?? $orig.topologicalPath,
          config: config ?? $orig.config,
          thisShouldBeAHandle: thisShouldBeAHandle ?? $orig.thisShouldBeAHandle,
        );

  TestAddEthernetDeviceRequest._(List<Object> argv)
      : topologicalPath = argv[0],
        config = argv[1],
        thisShouldBeAHandle = argv[2];
  final String topologicalPath;
  final InterfaceConfig config;
  final int thisShouldBeAHandle;

  @override
  List<Object> get $fields {
    return <Object>[
      topologicalPath,
      config,
      thisShouldBeAHandle,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TestAddEthernetDeviceRequest' r'(topologicalPath: ' +
        topologicalPath.toString() +
        r', config: ' +
        config.toString() +
        r', thisShouldBeAHandle: ' +
        thisShouldBeAHandle.toString() +
        r')';
  }

  static TestAddEthernetDeviceRequest _ctor(List<Object> argv) =>
      TestAddEthernetDeviceRequest._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TestAddEthernetDeviceRequest>
    kTestAddEthernetDeviceRequest_Type =
    $fidl.StructType<TestAddEthernetDeviceRequest>(
  inlineSizeOld: 72,
  inlineSizeV1: 64,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<InterfaceConfig>(
        type: kInterfaceConfig_Type, offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 64, offsetV1: 56),
  ],
  ctor: TestAddEthernetDeviceRequest._ctor,
);

class NodeAttributes extends $fidl.Struct {
  const NodeAttributes({
    @required this.mode,
    @required this.id,
    @required this.contentSize,
    @required this.storageSize,
    @required this.linkCount,
    @required this.creationTime,
    @required this.modificationTime,
  });
  NodeAttributes.clone(
    NodeAttributes $orig, {
    int mode,
    int id,
    int contentSize,
    int storageSize,
    int linkCount,
    int creationTime,
    int modificationTime,
  }) : this(
          mode: mode ?? $orig.mode,
          id: id ?? $orig.id,
          contentSize: contentSize ?? $orig.contentSize,
          storageSize: storageSize ?? $orig.storageSize,
          linkCount: linkCount ?? $orig.linkCount,
          creationTime: creationTime ?? $orig.creationTime,
          modificationTime: modificationTime ?? $orig.modificationTime,
        );

  NodeAttributes._(List<Object> argv)
      : mode = argv[0],
        id = argv[1],
        contentSize = argv[2],
        storageSize = argv[3],
        linkCount = argv[4],
        creationTime = argv[5],
        modificationTime = argv[6];
  final int mode;
  final int id;
  final int contentSize;
  final int storageSize;
  final int linkCount;
  final int creationTime;
  final int modificationTime;

  @override
  List<Object> get $fields {
    return <Object>[
      mode,
      id,
      contentSize,
      storageSize,
      linkCount,
      creationTime,
      modificationTime,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'NodeAttributes' r'(mode: ' +
        mode.toString() +
        r', id: ' +
        id.toString() +
        r', contentSize: ' +
        contentSize.toString() +
        r', storageSize: ' +
        storageSize.toString() +
        r', linkCount: ' +
        linkCount.toString() +
        r', creationTime: ' +
        creationTime.toString() +
        r', modificationTime: ' +
        modificationTime.toString() +
        r')';
  }

  static NodeAttributes _ctor(List<Object> argv) => NodeAttributes._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<NodeAttributes> kNodeAttributes_Type =
    $fidl.StructType<NodeAttributes>(
  inlineSizeOld: 56,
  inlineSizeV1: 56,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 24, offsetV1: 24),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 32, offsetV1: 32),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 40, offsetV1: 40),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 48, offsetV1: 48),
  ],
  ctor: NodeAttributes._ctor,
);

class FileGetAttrResponse extends $fidl.Struct {
  const FileGetAttrResponse({
    @required this.s,
    @required this.attributes,
  });
  FileGetAttrResponse.clone(
    FileGetAttrResponse $orig, {
    int s,
    NodeAttributes attributes,
  }) : this(
          s: s ?? $orig.s,
          attributes: attributes ?? $orig.attributes,
        );

  FileGetAttrResponse._(List<Object> argv)
      : s = argv[0],
        attributes = argv[1];
  final int s;
  final NodeAttributes attributes;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'FileGetAttrResponse' r'(s: ' +
        s.toString() +
        r', attributes: ' +
        attributes.toString() +
        r')';
  }

  static FileGetAttrResponse _ctor(List<Object> argv) =>
      FileGetAttrResponse._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<FileGetAttrResponse> kFileGetAttrResponse_Type =
    $fidl.StructType<FileGetAttrResponse>(
  inlineSizeOld: 64,
  inlineSizeV1: 64,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<NodeAttributes>(
        type: kNodeAttributes_Type, offsetOld: 8, offsetV1: 8),
  ],
  ctor: FileGetAttrResponse._ctor,
);

class UnionWithBoundStringStruct extends $fidl.Struct {
  const UnionWithBoundStringStruct({
    @required this.v,
  });
  UnionWithBoundStringStruct.clone(
    UnionWithBoundStringStruct $orig, {
    UnionWithBoundString v,
  }) : this(
          v: v ?? $orig.v,
        );

  UnionWithBoundStringStruct._(List<Object> argv) : v = argv[0];
  final UnionWithBoundString v;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'UnionWithBoundStringStruct' r'(v: ' + v.toString() + r')';
  }

  static UnionWithBoundStringStruct _ctor(List<Object> argv) =>
      UnionWithBoundStringStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<UnionWithBoundStringStruct>
    kUnionWithBoundStringStruct_Type =
    $fidl.StructType<UnionWithBoundStringStruct>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<UnionWithBoundString>(
        type: kUnionWithBoundString_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: UnionWithBoundStringStruct._ctor,
);

class SingleVariantUnionStruct extends $fidl.Struct {
  const SingleVariantUnionStruct({
    @required this.u,
  });
  SingleVariantUnionStruct.clone(
    SingleVariantUnionStruct $orig, {
    SingleVariantUnion u,
  }) : this(
          u: u ?? $orig.u,
        );

  SingleVariantUnionStruct._(List<Object> argv) : u = argv[0];
  final SingleVariantUnion u;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'SingleVariantUnionStruct' r'(u: ' + u.toString() + r')';
  }

  static SingleVariantUnionStruct _ctor(List<Object> argv) =>
      SingleVariantUnionStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<SingleVariantUnionStruct>
    kSingleVariantUnionStruct_Type = $fidl.StructType<SingleVariantUnionStruct>(
  inlineSizeOld: 8,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<SingleVariantUnion>(
        type: kSingleVariantUnion_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: SingleVariantUnionStruct._ctor,
);

class ReverseOrdinalUnionStruct extends $fidl.Struct {
  const ReverseOrdinalUnionStruct({
    @required this.u,
  });
  ReverseOrdinalUnionStruct.clone(
    ReverseOrdinalUnionStruct $orig, {
    ReverseOrdinalUnion u,
  }) : this(
          u: u ?? $orig.u,
        );

  ReverseOrdinalUnionStruct._(List<Object> argv) : u = argv[0];
  final ReverseOrdinalUnion u;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'ReverseOrdinalUnionStruct' r'(u: ' + u.toString() + r')';
  }

  static ReverseOrdinalUnionStruct _ctor(List<Object> argv) =>
      ReverseOrdinalUnionStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ReverseOrdinalUnionStruct>
    kReverseOrdinalUnionStruct_Type =
    $fidl.StructType<ReverseOrdinalUnionStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<ReverseOrdinalUnion>(
        type: kReverseOrdinalUnion_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: ReverseOrdinalUnionStruct._ctor,
);

class StructWithInt extends $fidl.Struct {
  const StructWithInt({
    @required this.x,
  });
  StructWithInt.clone(
    StructWithInt $orig, {
    int x,
  }) : this(
          x: x ?? $orig.x,
        );

  StructWithInt._(List<Object> argv) : x = argv[0];
  final int x;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructWithInt' r'(x: ' + x.toString() + r')';
  }

  static StructWithInt _ctor(List<Object> argv) => StructWithInt._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithInt> kStructWithInt_Type =
    $fidl.StructType<StructWithInt>(
  inlineSizeOld: 4,
  inlineSizeV1: 4,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: StructWithInt._ctor,
);

class StructWithArrays extends $fidl.Struct {
  const StructWithArrays({
    @required this.arrInt,
    @required this.arrString,
    @required this.arrNullableString,
    @required this.arrStruct,
    @required this.arrNullableStruct,
    @required this.arrArrInt,
  });
  StructWithArrays.clone(
    StructWithArrays $orig, {
    Int32List arrInt,
    List<String> arrString,
    List<String> arrNullableString,
    List<StructWithInt> arrStruct,
    List<StructWithInt> arrNullableStruct,
    List<Int32List> arrArrInt,
  }) : this(
          arrInt: arrInt ?? $orig.arrInt,
          arrString: arrString ?? $orig.arrString,
          arrNullableString: arrNullableString ?? $orig.arrNullableString,
          arrStruct: arrStruct ?? $orig.arrStruct,
          arrNullableStruct: arrNullableStruct ?? $orig.arrNullableStruct,
          arrArrInt: arrArrInt ?? $orig.arrArrInt,
        );

  StructWithArrays._(List<Object> argv)
      : arrInt = argv[0],
        arrString = argv[1],
        arrNullableString = argv[2],
        arrStruct = argv[3],
        arrNullableStruct = argv[4],
        arrArrInt = argv[5];
  final Int32List arrInt;
  final List<String> arrString;
  final List<String> arrNullableString;
  final List<StructWithInt> arrStruct;
  final List<StructWithInt> arrNullableStruct;
  final List<Int32List> arrArrInt;

  @override
  List<Object> get $fields {
    return <Object>[
      arrInt,
      arrString,
      arrNullableString,
      arrStruct,
      arrNullableStruct,
      arrArrInt,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructWithArrays' r'(arrInt: ' +
        arrInt.toString() +
        r', arrString: ' +
        arrString.toString() +
        r', arrNullableString: ' +
        arrNullableString.toString() +
        r', arrStruct: ' +
        arrStruct.toString() +
        r', arrNullableStruct: ' +
        arrNullableStruct.toString() +
        r', arrArrInt: ' +
        arrArrInt.toString() +
        r')';
  }

  static StructWithArrays _ctor(List<Object> argv) => StructWithArrays._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithArrays> kStructWithArrays_Type =
    $fidl.StructType<StructWithArrays>(
  inlineSizeOld: 120,
  inlineSizeV1: 120,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Int32List>(
        type: $fidl.ArrayType<Int32List>(
            element: $fidl.Int32Type(), elementCount: 2),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<List<String>>(
        type: $fidl.ArrayType<List<String>>(
            element: $fidl.StringType(maybeElementCount: null, nullable: false),
            elementCount: 2),
        offsetOld: 8,
        offsetV1: 8),
    $fidl.MemberType<List<String>>(
        type: $fidl.ArrayType<List<String>>(
            element: $fidl.StringType(maybeElementCount: null, nullable: true),
            elementCount: 2),
        offsetOld: 40,
        offsetV1: 40),
    $fidl.MemberType<List<StructWithInt>>(
        type: $fidl.ArrayType<List<StructWithInt>>(
            element: kStructWithInt_Type, elementCount: 2),
        offsetOld: 72,
        offsetV1: 72),
    $fidl.MemberType<List<StructWithInt>>(
        type: $fidl.ArrayType<List<StructWithInt>>(
            element:
                $fidl.PointerType<StructWithInt>(element: kStructWithInt_Type),
            elementCount: 2),
        offsetOld: 80,
        offsetV1: 80),
    $fidl.MemberType<List<Int32List>>(
        type: $fidl.ArrayType<List<Int32List>>(
            element: $fidl.ArrayType<Int32List>(
                element: $fidl.Int32Type(), elementCount: 3),
            elementCount: 2),
        offsetOld: 96,
        offsetV1: 96),
  ],
  ctor: StructWithArrays._ctor,
);

class StructWithVectors extends $fidl.Struct {
  const StructWithVectors({
    @required this.vecEmpty,
    @required this.vecInt,
    @required this.vecString,
    @required this.vecNullableString,
    @required this.vecStruct,
    @required this.vecNullableStruct,
    @required this.vecVecInt,
  });
  StructWithVectors.clone(
    StructWithVectors $orig, {
    Int32List vecEmpty,
    Int32List vecInt,
    List<String> vecString,
    List<String> vecNullableString,
    List<StructWithInt> vecStruct,
    List<StructWithInt> vecNullableStruct,
    List<Int32List> vecVecInt,
  }) : this(
          vecEmpty: vecEmpty ?? $orig.vecEmpty,
          vecInt: vecInt ?? $orig.vecInt,
          vecString: vecString ?? $orig.vecString,
          vecNullableString: vecNullableString ?? $orig.vecNullableString,
          vecStruct: vecStruct ?? $orig.vecStruct,
          vecNullableStruct: vecNullableStruct ?? $orig.vecNullableStruct,
          vecVecInt: vecVecInt ?? $orig.vecVecInt,
        );

  StructWithVectors._(List<Object> argv)
      : vecEmpty = argv[0],
        vecInt = argv[1],
        vecString = argv[2],
        vecNullableString = argv[3],
        vecStruct = argv[4],
        vecNullableStruct = argv[5],
        vecVecInt = argv[6];
  final Int32List vecEmpty;
  final Int32List vecInt;
  final List<String> vecString;
  final List<String> vecNullableString;
  final List<StructWithInt> vecStruct;
  final List<StructWithInt> vecNullableStruct;
  final List<Int32List> vecVecInt;

  @override
  List<Object> get $fields {
    return <Object>[
      vecEmpty,
      vecInt,
      vecString,
      vecNullableString,
      vecStruct,
      vecNullableStruct,
      vecVecInt,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructWithVectors' r'(vecEmpty: ' +
        vecEmpty.toString() +
        r', vecInt: ' +
        vecInt.toString() +
        r', vecString: ' +
        vecString.toString() +
        r', vecNullableString: ' +
        vecNullableString.toString() +
        r', vecStruct: ' +
        vecStruct.toString() +
        r', vecNullableStruct: ' +
        vecNullableStruct.toString() +
        r', vecVecInt: ' +
        vecVecInt.toString() +
        r')';
  }

  static StructWithVectors _ctor(List<Object> argv) =>
      StructWithVectors._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithVectors> kStructWithVectors_Type =
    $fidl.StructType<StructWithVectors>(
  inlineSizeOld: 112,
  inlineSizeV1: 112,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Int32List>(
        type: $fidl.VectorType<Int32List>(
            element: $fidl.Int32Type(),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<Int32List>(
        type: $fidl.VectorType<Int32List>(
            element: $fidl.Int32Type(),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 16,
        offsetV1: 16),
    $fidl.MemberType<List<String>>(
        type: $fidl.VectorType<List<String>>(
            element: $fidl.StringType(maybeElementCount: null, nullable: false),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 32,
        offsetV1: 32),
    $fidl.MemberType<List<String>>(
        type: $fidl.VectorType<List<String>>(
            element: $fidl.StringType(maybeElementCount: null, nullable: true),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 48,
        offsetV1: 48),
    $fidl.MemberType<List<StructWithInt>>(
        type: $fidl.VectorType<List<StructWithInt>>(
            element: kStructWithInt_Type,
            maybeElementCount: null,
            nullable: false),
        offsetOld: 64,
        offsetV1: 64),
    $fidl.MemberType<List<StructWithInt>>(
        type: $fidl.VectorType<List<StructWithInt>>(
            element:
                $fidl.PointerType<StructWithInt>(element: kStructWithInt_Type),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 80,
        offsetV1: 80),
    $fidl.MemberType<List<Int32List>>(
        type: $fidl.VectorType<List<Int32List>>(
            element: $fidl.VectorType<Int32List>(
                element: $fidl.Int32Type(),
                maybeElementCount: null,
                nullable: false),
            maybeElementCount: null,
            nullable: false),
        offsetOld: 96,
        offsetV1: 96),
  ],
  ctor: StructWithVectors._ctor,
);

class EmptyStruct extends $fidl.Struct {
  const EmptyStruct({
    this.reserved: 0x0,
  });
  EmptyStruct.clone(
    EmptyStruct $orig, {
    int reserved,
  }) : this(
          reserved: reserved ?? $orig.reserved,
        );

  EmptyStruct._(List<Object> argv) : reserved = argv[0];
  final int reserved;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'EmptyStruct' r'(reserved: ' + reserved.toString() + r')';
  }

  static EmptyStruct _ctor(List<Object> argv) => EmptyStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<EmptyStruct> kEmptyStruct_Type =
    $fidl.StructType<EmptyStruct>(
  inlineSizeOld: 1,
  inlineSizeV1: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: EmptyStruct._ctor,
);

class EmptyStructSandwich extends $fidl.Struct {
  const EmptyStructSandwich({
    @required this.before,
    @required this.es,
    @required this.after,
  });
  EmptyStructSandwich.clone(
    EmptyStructSandwich $orig, {
    String before,
    EmptyStruct es,
    String after,
  }) : this(
          before: before ?? $orig.before,
          es: es ?? $orig.es,
          after: after ?? $orig.after,
        );

  EmptyStructSandwich._(List<Object> argv)
      : before = argv[0],
        es = argv[1],
        after = argv[2];
  final String before;
  final EmptyStruct es;
  final String after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      es,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'EmptyStructSandwich' r'(before: ' +
        before.toString() +
        r', es: ' +
        es.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static EmptyStructSandwich _ctor(List<Object> argv) =>
      EmptyStructSandwich._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<EmptyStructSandwich> kEmptyStructSandwich_Type =
    $fidl.StructType<EmptyStructSandwich>(
  inlineSizeOld: 40,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<EmptyStruct>(
        type: kEmptyStruct_Type, offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 24,
        offsetV1: 24),
  ],
  ctor: EmptyStructSandwich._ctor,
);

class Uint8Uint16Uint32Uint64 extends $fidl.Struct {
  const Uint8Uint16Uint32Uint64({
    @required this.f1,
    @required this.f2,
    @required this.f3,
    @required this.f4,
  });
  Uint8Uint16Uint32Uint64.clone(
    Uint8Uint16Uint32Uint64 $orig, {
    int f1,
    int f2,
    int f3,
    int f4,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
          f3: f3 ?? $orig.f3,
          f4: f4 ?? $orig.f4,
        );

  Uint8Uint16Uint32Uint64._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1],
        f3 = argv[2],
        f4 = argv[3];
  final int f1;
  final int f2;
  final int f3;
  final int f4;

  @override
  List<Object> get $fields {
    return <Object>[
      f1,
      f2,
      f3,
      f4,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Uint8Uint16Uint32Uint64' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r', f3: ' +
        f3.toString() +
        r', f4: ' +
        f4.toString() +
        r')';
  }

  static Uint8Uint16Uint32Uint64 _ctor(List<Object> argv) =>
      Uint8Uint16Uint32Uint64._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Uint8Uint16Uint32Uint64> kUint8Uint16Uint32Uint64_Type =
    $fidl.StructType<Uint8Uint16Uint32Uint64>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint16Type(), offsetOld: 2, offsetV1: 2),
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 4, offsetV1: 4),
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 8, offsetV1: 8),
  ],
  ctor: Uint8Uint16Uint32Uint64._ctor,
);

class Uint64Uint32Uint16Uint8 extends $fidl.Struct {
  const Uint64Uint32Uint16Uint8({
    @required this.f1,
    @required this.f2,
    @required this.f3,
    @required this.f4,
  });
  Uint64Uint32Uint16Uint8.clone(
    Uint64Uint32Uint16Uint8 $orig, {
    int f1,
    int f2,
    int f3,
    int f4,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
          f3: f3 ?? $orig.f3,
          f4: f4 ?? $orig.f4,
        );

  Uint64Uint32Uint16Uint8._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1],
        f3 = argv[2],
        f4 = argv[3];
  final int f1;
  final int f2;
  final int f3;
  final int f4;

  @override
  List<Object> get $fields {
    return <Object>[
      f1,
      f2,
      f3,
      f4,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Uint64Uint32Uint16Uint8' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r', f3: ' +
        f3.toString() +
        r', f4: ' +
        f4.toString() +
        r')';
  }

  static Uint64Uint32Uint16Uint8 _ctor(List<Object> argv) =>
      Uint64Uint32Uint16Uint8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Uint64Uint32Uint16Uint8> kUint64Uint32Uint16Uint8_Type =
    $fidl.StructType<Uint64Uint32Uint16Uint8>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint16Type(), offsetOld: 12, offsetV1: 12),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 14, offsetV1: 14),
  ],
  ctor: Uint64Uint32Uint16Uint8._ctor,
);

class Length2StringWrapper extends $fidl.Struct {
  const Length2StringWrapper({
    @required this.length2String,
  });
  Length2StringWrapper.clone(
    Length2StringWrapper $orig, {
    String length2String,
  }) : this(
          length2String: length2String ?? $orig.length2String,
        );

  Length2StringWrapper._(List<Object> argv) : length2String = argv[0];
  final String length2String;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Length2StringWrapper' r'(length2String: ' +
        length2String.toString() +
        r')';
  }

  static Length2StringWrapper _ctor(List<Object> argv) =>
      Length2StringWrapper._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Length2StringWrapper> kLength2StringWrapper_Type =
    $fidl.StructType<Length2StringWrapper>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: 2, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Length2StringWrapper._ctor,
);

class StringWrapper extends $fidl.Struct {
  const StringWrapper({
    @required this.str,
  });
  StringWrapper.clone(
    StringWrapper $orig, {
    String str,
  }) : this(
          str: str ?? $orig.str,
        );

  StringWrapper._(List<Object> argv) : str = argv[0];
  final String str;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StringWrapper' r'(str: ' + str.toString() + r')';
  }

  static StringWrapper _ctor(List<Object> argv) => StringWrapper._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StringWrapper> kStringWrapper_Type =
    $fidl.StructType<StringWrapper>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: StringWrapper._ctor,
);

class StructOfSimpleTable extends $fidl.Struct {
  const StructOfSimpleTable({
    @required this.table,
  });
  StructOfSimpleTable.clone(
    StructOfSimpleTable $orig, {
    SimpleTable table,
  }) : this(
          table: table ?? $orig.table,
        );

  StructOfSimpleTable._(List<Object> argv) : table = argv[0];
  final SimpleTable table;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructOfSimpleTable' r'(table: ' + table.toString() + r')';
  }

  static StructOfSimpleTable _ctor(List<Object> argv) =>
      StructOfSimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructOfSimpleTable> kStructOfSimpleTable_Type =
    $fidl.StructType<StructOfSimpleTable>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<SimpleTable>(
        type: kSimpleTable_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: StructOfSimpleTable._ctor,
);

class SimpleTableThenUint64 extends $fidl.Struct {
  const SimpleTableThenUint64({
    @required this.table,
    @required this.number,
  });
  SimpleTableThenUint64.clone(
    SimpleTableThenUint64 $orig, {
    SimpleTable table,
    int number,
  }) : this(
          table: table ?? $orig.table,
          number: number ?? $orig.number,
        );

  SimpleTableThenUint64._(List<Object> argv)
      : table = argv[0],
        number = argv[1];
  final SimpleTable table;
  final int number;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'SimpleTableThenUint64' r'(table: ' +
        table.toString() +
        r', number: ' +
        number.toString() +
        r')';
  }

  static SimpleTableThenUint64 _ctor(List<Object> argv) =>
      SimpleTableThenUint64._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<SimpleTableThenUint64> kSimpleTableThenUint64_Type =
    $fidl.StructType<SimpleTableThenUint64>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<SimpleTable>(
        type: kSimpleTable_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 16, offsetV1: 16),
  ],
  ctor: SimpleTableThenUint64._ctor,
);

class StructOfTableWithStringAndVector extends $fidl.Struct {
  const StructOfTableWithStringAndVector({
    @required this.table,
  });
  StructOfTableWithStringAndVector.clone(
    StructOfTableWithStringAndVector $orig, {
    TableWithStringAndVector table,
  }) : this(
          table: table ?? $orig.table,
        );

  StructOfTableWithStringAndVector._(List<Object> argv) : table = argv[0];
  final TableWithStringAndVector table;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructOfTableWithStringAndVector' r'(table: ' +
        table.toString() +
        r')';
  }

  static StructOfTableWithStringAndVector _ctor(List<Object> argv) =>
      StructOfTableWithStringAndVector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructOfTableWithStringAndVector>
    kStructOfTableWithStringAndVector_Type =
    $fidl.StructType<StructOfTableWithStringAndVector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<TableWithStringAndVector>(
        type: kTableWithStringAndVector_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: StructOfTableWithStringAndVector._ctor,
);

class ThreeByte extends $fidl.Struct {
  const ThreeByte({
    @required this.elem1,
    @required this.elem2,
    @required this.elem3,
  });
  ThreeByte.clone(
    ThreeByte $orig, {
    int elem1,
    int elem2,
    int elem3,
  }) : this(
          elem1: elem1 ?? $orig.elem1,
          elem2: elem2 ?? $orig.elem2,
          elem3: elem3 ?? $orig.elem3,
        );

  ThreeByte._(List<Object> argv)
      : elem1 = argv[0],
        elem2 = argv[1],
        elem3 = argv[2];
  final int elem1;
  final int elem2;
  final int elem3;

  @override
  List<Object> get $fields {
    return <Object>[
      elem1,
      elem2,
      elem3,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'ThreeByte' r'(elem1: ' +
        elem1.toString() +
        r', elem2: ' +
        elem2.toString() +
        r', elem3: ' +
        elem3.toString() +
        r')';
  }

  static ThreeByte _ctor(List<Object> argv) => ThreeByte._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ThreeByte> kThreeByte_Type = $fidl.StructType<ThreeByte>(
  inlineSizeOld: 3,
  inlineSizeV1: 3,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 1, offsetV1: 1),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 2, offsetV1: 2),
  ],
  ctor: ThreeByte._ctor,
);

class FiveByte extends $fidl.Struct {
  const FiveByte({
    @required this.elem1,
    @required this.elem2,
  });
  FiveByte.clone(
    FiveByte $orig, {
    int elem1,
    int elem2,
  }) : this(
          elem1: elem1 ?? $orig.elem1,
          elem2: elem2 ?? $orig.elem2,
        );

  FiveByte._(List<Object> argv)
      : elem1 = argv[0],
        elem2 = argv[1];
  final int elem1;
  final int elem2;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'FiveByte' r'(elem1: ' +
        elem1.toString() +
        r', elem2: ' +
        elem2.toString() +
        r')';
  }

  static FiveByte _ctor(List<Object> argv) => FiveByte._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<FiveByte> kFiveByte_Type = $fidl.StructType<FiveByte>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: 4),
  ],
  ctor: FiveByte._ctor,
);

class ThreeByteInStruct extends $fidl.Struct {
  const ThreeByteInStruct({
    @required this.elem1,
    @required this.elem2,
    @required this.elem3,
  });
  ThreeByteInStruct.clone(
    ThreeByteInStruct $orig, {
    ThreeByte elem1,
    ThreeByte elem2,
    ThreeByte elem3,
  }) : this(
          elem1: elem1 ?? $orig.elem1,
          elem2: elem2 ?? $orig.elem2,
          elem3: elem3 ?? $orig.elem3,
        );

  ThreeByteInStruct._(List<Object> argv)
      : elem1 = argv[0],
        elem2 = argv[1],
        elem3 = argv[2];
  final ThreeByte elem1;
  final ThreeByte elem2;
  final ThreeByte elem3;

  @override
  List<Object> get $fields {
    return <Object>[
      elem1,
      elem2,
      elem3,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'ThreeByteInStruct' r'(elem1: ' +
        elem1.toString() +
        r', elem2: ' +
        elem2.toString() +
        r', elem3: ' +
        elem3.toString() +
        r')';
  }

  static ThreeByteInStruct _ctor(List<Object> argv) =>
      ThreeByteInStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ThreeByteInStruct> kThreeByteInStruct_Type =
    $fidl.StructType<ThreeByteInStruct>(
  inlineSizeOld: 9,
  inlineSizeV1: 9,
  members: <$fidl.MemberType>[
    $fidl.MemberType<ThreeByte>(
        type: kThreeByte_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<ThreeByte>(
        type: kThreeByte_Type, offsetOld: 3, offsetV1: 3),
    $fidl.MemberType<ThreeByte>(
        type: kThreeByte_Type, offsetOld: 6, offsetV1: 6),
  ],
  ctor: ThreeByteInStruct._ctor,
);

class FiveByteInStruct extends $fidl.Struct {
  const FiveByteInStruct({
    @required this.elem1,
    @required this.elem2,
    @required this.elem3,
  });
  FiveByteInStruct.clone(
    FiveByteInStruct $orig, {
    FiveByte elem1,
    FiveByte elem2,
    FiveByte elem3,
  }) : this(
          elem1: elem1 ?? $orig.elem1,
          elem2: elem2 ?? $orig.elem2,
          elem3: elem3 ?? $orig.elem3,
        );

  FiveByteInStruct._(List<Object> argv)
      : elem1 = argv[0],
        elem2 = argv[1],
        elem3 = argv[2];
  final FiveByte elem1;
  final FiveByte elem2;
  final FiveByte elem3;

  @override
  List<Object> get $fields {
    return <Object>[
      elem1,
      elem2,
      elem3,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'FiveByteInStruct' r'(elem1: ' +
        elem1.toString() +
        r', elem2: ' +
        elem2.toString() +
        r', elem3: ' +
        elem3.toString() +
        r')';
  }

  static FiveByteInStruct _ctor(List<Object> argv) => FiveByteInStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<FiveByteInStruct> kFiveByteInStruct_Type =
    $fidl.StructType<FiveByteInStruct>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<FiveByte>(type: kFiveByte_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<FiveByte>(type: kFiveByte_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<FiveByte>(
        type: kFiveByte_Type, offsetOld: 16, offsetV1: 16),
  ],
  ctor: FiveByteInStruct._ctor,
);

class ThreeByteInVector extends $fidl.Struct {
  const ThreeByteInVector({
    @required this.elems,
  });
  ThreeByteInVector.clone(
    ThreeByteInVector $orig, {
    List<ThreeByte> elems,
  }) : this(
          elems: elems ?? $orig.elems,
        );

  ThreeByteInVector._(List<Object> argv) : elems = argv[0];
  final List<ThreeByte> elems;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'ThreeByteInVector' r'(elems: ' + elems.toString() + r')';
  }

  static ThreeByteInVector _ctor(List<Object> argv) =>
      ThreeByteInVector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ThreeByteInVector> kThreeByteInVector_Type =
    $fidl.StructType<ThreeByteInVector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<ThreeByte>>(
        type: $fidl.VectorType<List<ThreeByte>>(
            element: kThreeByte_Type, maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: ThreeByteInVector._ctor,
);

class FiveByteInVector extends $fidl.Struct {
  const FiveByteInVector({
    @required this.elems,
  });
  FiveByteInVector.clone(
    FiveByteInVector $orig, {
    List<FiveByte> elems,
  }) : this(
          elems: elems ?? $orig.elems,
        );

  FiveByteInVector._(List<Object> argv) : elems = argv[0];
  final List<FiveByte> elems;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'FiveByteInVector' r'(elems: ' + elems.toString() + r')';
  }

  static FiveByteInVector _ctor(List<Object> argv) => FiveByteInVector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<FiveByteInVector> kFiveByteInVector_Type =
    $fidl.StructType<FiveByteInVector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<FiveByte>>(
        type: $fidl.VectorType<List<FiveByte>>(
            element: kFiveByte_Type, maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: FiveByteInVector._ctor,
);

class ThreeByteInArray extends $fidl.Struct {
  const ThreeByteInArray({
    @required this.elems,
  });
  ThreeByteInArray.clone(
    ThreeByteInArray $orig, {
    List<ThreeByte> elems,
  }) : this(
          elems: elems ?? $orig.elems,
        );

  ThreeByteInArray._(List<Object> argv) : elems = argv[0];
  final List<ThreeByte> elems;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'ThreeByteInArray' r'(elems: ' + elems.toString() + r')';
  }

  static ThreeByteInArray _ctor(List<Object> argv) => ThreeByteInArray._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ThreeByteInArray> kThreeByteInArray_Type =
    $fidl.StructType<ThreeByteInArray>(
  inlineSizeOld: 9,
  inlineSizeV1: 9,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<ThreeByte>>(
        type: $fidl.ArrayType<List<ThreeByte>>(
            element: kThreeByte_Type, elementCount: 3),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: ThreeByteInArray._ctor,
);

class FiveByteInArray extends $fidl.Struct {
  const FiveByteInArray({
    @required this.elems,
  });
  FiveByteInArray.clone(
    FiveByteInArray $orig, {
    List<FiveByte> elems,
  }) : this(
          elems: elems ?? $orig.elems,
        );

  FiveByteInArray._(List<Object> argv) : elems = argv[0];
  final List<FiveByte> elems;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'FiveByteInArray' r'(elems: ' + elems.toString() + r')';
  }

  static FiveByteInArray _ctor(List<Object> argv) => FiveByteInArray._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<FiveByteInArray> kFiveByteInArray_Type =
    $fidl.StructType<FiveByteInArray>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<FiveByte>>(
        type: $fidl.ArrayType<List<FiveByte>>(
            element: kFiveByte_Type, elementCount: 3),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: FiveByteInArray._ctor,
);

class MyBool extends $fidl.Struct {
  const MyBool({
    @required this.value,
  });
  MyBool.clone(
    MyBool $orig, {
    bool value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyBool._(List<Object> argv) : value = argv[0];
  final bool value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyBool' r'(value: ' + value.toString() + r')';
  }

  static MyBool _ctor(List<Object> argv) => MyBool._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyBool> kMyBool_Type = $fidl.StructType<MyBool>(
  inlineSizeOld: 1,
  inlineSizeV1: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<bool>(type: $fidl.BoolType(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyBool._ctor,
);

class MyByte extends $fidl.Struct {
  const MyByte({
    @required this.value,
  });
  MyByte.clone(
    MyByte $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyByte._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyByte' r'(value: ' + value.toString() + r')';
  }

  static MyByte _ctor(List<Object> argv) => MyByte._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyByte> kMyByte_Type = $fidl.StructType<MyByte>(
  inlineSizeOld: 1,
  inlineSizeV1: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyByte._ctor,
);

class MyInt8 extends $fidl.Struct {
  const MyInt8({
    @required this.value,
  });
  MyInt8.clone(
    MyInt8 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyInt8._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyInt8' r'(value: ' + value.toString() + r')';
  }

  static MyInt8 _ctor(List<Object> argv) => MyInt8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyInt8> kMyInt8_Type = $fidl.StructType<MyInt8>(
  inlineSizeOld: 1,
  inlineSizeV1: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int8Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyInt8._ctor,
);

class MyInt16 extends $fidl.Struct {
  const MyInt16({
    @required this.value,
  });
  MyInt16.clone(
    MyInt16 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyInt16._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyInt16' r'(value: ' + value.toString() + r')';
  }

  static MyInt16 _ctor(List<Object> argv) => MyInt16._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyInt16> kMyInt16_Type = $fidl.StructType<MyInt16>(
  inlineSizeOld: 2,
  inlineSizeV1: 2,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int16Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyInt16._ctor,
);

class MyInt32 extends $fidl.Struct {
  const MyInt32({
    @required this.value,
  });
  MyInt32.clone(
    MyInt32 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyInt32._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyInt32' r'(value: ' + value.toString() + r')';
  }

  static MyInt32 _ctor(List<Object> argv) => MyInt32._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyInt32> kMyInt32_Type = $fidl.StructType<MyInt32>(
  inlineSizeOld: 4,
  inlineSizeV1: 4,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyInt32._ctor,
);

class MyInt64 extends $fidl.Struct {
  const MyInt64({
    @required this.value,
  });
  MyInt64.clone(
    MyInt64 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyInt64._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyInt64' r'(value: ' + value.toString() + r')';
  }

  static MyInt64 _ctor(List<Object> argv) => MyInt64._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyInt64> kMyInt64_Type = $fidl.StructType<MyInt64>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyInt64._ctor,
);

class MyUint8 extends $fidl.Struct {
  const MyUint8({
    @required this.value,
  });
  MyUint8.clone(
    MyUint8 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyUint8._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyUint8' r'(value: ' + value.toString() + r')';
  }

  static MyUint8 _ctor(List<Object> argv) => MyUint8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyUint8> kMyUint8_Type = $fidl.StructType<MyUint8>(
  inlineSizeOld: 1,
  inlineSizeV1: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyUint8._ctor,
);

class MyUint16 extends $fidl.Struct {
  const MyUint16({
    @required this.value,
  });
  MyUint16.clone(
    MyUint16 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyUint16._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyUint16' r'(value: ' + value.toString() + r')';
  }

  static MyUint16 _ctor(List<Object> argv) => MyUint16._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyUint16> kMyUint16_Type = $fidl.StructType<MyUint16>(
  inlineSizeOld: 2,
  inlineSizeV1: 2,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint16Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyUint16._ctor,
);

class MyUint32 extends $fidl.Struct {
  const MyUint32({
    @required this.value,
  });
  MyUint32.clone(
    MyUint32 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyUint32._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyUint32' r'(value: ' + value.toString() + r')';
  }

  static MyUint32 _ctor(List<Object> argv) => MyUint32._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyUint32> kMyUint32_Type = $fidl.StructType<MyUint32>(
  inlineSizeOld: 4,
  inlineSizeV1: 4,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyUint32._ctor,
);

class MyUint64 extends $fidl.Struct {
  const MyUint64({
    @required this.value,
  });
  MyUint64.clone(
    MyUint64 $orig, {
    int value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyUint64._(List<Object> argv) : value = argv[0];
  final int value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyUint64' r'(value: ' + value.toString() + r')';
  }

  static MyUint64 _ctor(List<Object> argv) => MyUint64._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyUint64> kMyUint64_Type = $fidl.StructType<MyUint64>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyUint64._ctor,
);

class MyFloat32 extends $fidl.Struct {
  const MyFloat32({
    @required this.value,
  });
  MyFloat32.clone(
    MyFloat32 $orig, {
    double value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyFloat32._(List<Object> argv) : value = argv[0];
  final double value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyFloat32' r'(value: ' + value.toString() + r')';
  }

  static MyFloat32 _ctor(List<Object> argv) => MyFloat32._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyFloat32> kMyFloat32_Type = $fidl.StructType<MyFloat32>(
  inlineSizeOld: 4,
  inlineSizeV1: 4,
  members: <$fidl.MemberType>[
    $fidl.MemberType<double>(
        type: $fidl.Float32Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyFloat32._ctor,
);

class MyFloat64 extends $fidl.Struct {
  const MyFloat64({
    @required this.value,
  });
  MyFloat64.clone(
    MyFloat64 $orig, {
    double value,
  }) : this(
          value: value ?? $orig.value,
        );

  MyFloat64._(List<Object> argv) : value = argv[0];
  final double value;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'MyFloat64' r'(value: ' + value.toString() + r')';
  }

  static MyFloat64 _ctor(List<Object> argv) => MyFloat64._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<MyFloat64> kMyFloat64_Type = $fidl.StructType<MyFloat64>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<double>(
        type: $fidl.Float64Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: MyFloat64._ctor,
);

class StructWithOptionals extends $fidl.Struct {
  const StructWithOptionals({
    @required this.s,
    this.s2,
    @required this.t,
    @required this.xu,
    this.xu2,
    @required this.u,
    this.u2,
  });
  StructWithOptionals.clone(
    StructWithOptionals $orig, {
    EmptyStruct s,
    EmptyStruct s2,
    TableWithEmptyStruct t,
    XUnionWithEmptyStruct xu,
    XUnionWithEmptyStruct xu2,
    UnionWithEmptyStruct u,
    UnionWithEmptyStruct u2,
  }) : this(
          s: s ?? $orig.s,
          s2: s2 ?? $orig.s2,
          t: t ?? $orig.t,
          xu: xu ?? $orig.xu,
          xu2: xu2 ?? $orig.xu2,
          u: u ?? $orig.u,
          u2: u2 ?? $orig.u2,
        );

  StructWithOptionals.cloneWithout(
    StructWithOptionals $orig, {
    bool s2,
    bool xu2,
    bool u2,
  }) : this(
          s: $orig.s,
          s2: s2 ? null : $orig.s2,
          t: $orig.t,
          xu: $orig.xu,
          xu2: xu2 ? null : $orig.xu2,
          u: $orig.u,
          u2: u2 ? null : $orig.u2,
        );

  StructWithOptionals._(List<Object> argv)
      : s = argv[0],
        s2 = argv[1],
        t = argv[2],
        xu = argv[3],
        xu2 = argv[4],
        u = argv[5],
        u2 = argv[6];
  final EmptyStruct s;
  final EmptyStruct s2;
  final TableWithEmptyStruct t;
  final XUnionWithEmptyStruct xu;
  final XUnionWithEmptyStruct xu2;
  final UnionWithEmptyStruct u;
  final UnionWithEmptyStruct u2;

  @override
  List<Object> get $fields {
    return <Object>[
      s,
      s2,
      t,
      xu,
      xu2,
      u,
      u2,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructWithOptionals' r'(s: ' +
        s.toString() +
        r', s2: ' +
        s2.toString() +
        r', t: ' +
        t.toString() +
        r', xu: ' +
        xu.toString() +
        r', xu2: ' +
        xu2.toString() +
        r', u: ' +
        u.toString() +
        r', u2: ' +
        u2.toString() +
        r')';
  }

  static StructWithOptionals _ctor(List<Object> argv) =>
      StructWithOptionals._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithOptionals> kStructWithOptionals_Type =
    $fidl.StructType<StructWithOptionals>(
  inlineSizeOld: 104,
  inlineSizeV1: 128,
  members: <$fidl.MemberType>[
    $fidl.MemberType<EmptyStruct>(
        type: kEmptyStruct_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<EmptyStruct>(
        type: $fidl.PointerType<EmptyStruct>(element: kEmptyStruct_Type),
        offsetOld: 8,
        offsetV1: 8),
    $fidl.MemberType<TableWithEmptyStruct>(
        type: kTableWithEmptyStruct_Type, offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<XUnionWithEmptyStruct>(
        type: kXUnionWithEmptyStruct_Type, offsetOld: 32, offsetV1: 32),
    $fidl.MemberType<XUnionWithEmptyStruct>(
        type: kXUnionWithEmptyStruct_OptType, offsetOld: 56, offsetV1: 56),
    $fidl.MemberType<UnionWithEmptyStruct>(
        type: kUnionWithEmptyStruct_Type, offsetOld: 80, offsetV1: 80),
    $fidl.MemberType<UnionWithEmptyStruct>(
        type: $fidl.OptUnionType<UnionWithEmptyStruct>(
            element: kUnionWithEmptyStruct_Type),
        offsetOld: 96,
        offsetV1: 104),
  ],
  ctor: StructWithOptionals._ctor,
);

class StructSize16Align8 extends $fidl.Struct {
  const StructSize16Align8({
    @required this.f1,
    @required this.f2,
  });
  StructSize16Align8.clone(
    StructSize16Align8 $orig, {
    int f1,
    int f2,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
        );

  StructSize16Align8._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1];
  final int f1;
  final int f2;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructSize16Align8' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r')';
  }

  static StructSize16Align8 _ctor(List<Object> argv) =>
      StructSize16Align8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructSize16Align8> kStructSize16Align8_Type =
    $fidl.StructType<StructSize16Align8>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 8, offsetV1: 8),
  ],
  ctor: StructSize16Align8._ctor,
);

class Sandwich1 extends $fidl.Struct {
  const Sandwich1({
    @required this.before,
    @required this.theUnion,
    @required this.after,
  });
  Sandwich1.clone(
    Sandwich1 $orig, {
    int before,
    UnionSize8Align4 theUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          theUnion: theUnion ?? $orig.theUnion,
          after: after ?? $orig.after,
        );

  Sandwich1._(List<Object> argv)
      : before = argv[0],
        theUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionSize8Align4 theUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      theUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich1' r'(before: ' +
        before.toString() +
        r', theUnion: ' +
        theUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich1 _ctor(List<Object> argv) => Sandwich1._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich1> kSandwich1_Type = $fidl.StructType<Sandwich1>(
  inlineSizeOld: 16,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionSize8Align4>(
        type: kUnionSize8Align4_Type, offsetOld: 4, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 12, offsetV1: 32),
  ],
  ctor: Sandwich1._ctor,
);

class Sandwich1WithOptUnion extends $fidl.Struct {
  const Sandwich1WithOptUnion({
    @required this.before,
    this.optUnion,
    @required this.after,
  });
  Sandwich1WithOptUnion.clone(
    Sandwich1WithOptUnion $orig, {
    int before,
    UnionSize8Align4 optUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          optUnion: optUnion ?? $orig.optUnion,
          after: after ?? $orig.after,
        );

  Sandwich1WithOptUnion.cloneWithout(
    Sandwich1WithOptUnion $orig, {
    bool optUnion,
  }) : this(
          before: $orig.before,
          optUnion: optUnion ? null : $orig.optUnion,
          after: $orig.after,
        );

  Sandwich1WithOptUnion._(List<Object> argv)
      : before = argv[0],
        optUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionSize8Align4 optUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      optUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich1WithOptUnion' r'(before: ' +
        before.toString() +
        r', optUnion: ' +
        optUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich1WithOptUnion _ctor(List<Object> argv) =>
      Sandwich1WithOptUnion._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich1WithOptUnion> kSandwich1WithOptUnion_Type =
    $fidl.StructType<Sandwich1WithOptUnion>(
  inlineSizeOld: 24,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionSize8Align4>(
        type: $fidl.OptUnionType<UnionSize8Align4>(
            element: kUnionSize8Align4_Type),
        offsetOld: 8,
        offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 16, offsetV1: 32),
  ],
  ctor: Sandwich1WithOptUnion._ctor,
);

class Sandwich2 extends $fidl.Struct {
  const Sandwich2({
    @required this.before,
    @required this.theUnion,
    @required this.after,
  });
  Sandwich2.clone(
    Sandwich2 $orig, {
    int before,
    UnionSize12Align4 theUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          theUnion: theUnion ?? $orig.theUnion,
          after: after ?? $orig.after,
        );

  Sandwich2._(List<Object> argv)
      : before = argv[0],
        theUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionSize12Align4 theUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      theUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich2' r'(before: ' +
        before.toString() +
        r', theUnion: ' +
        theUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich2 _ctor(List<Object> argv) => Sandwich2._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich2> kSandwich2_Type = $fidl.StructType<Sandwich2>(
  inlineSizeOld: 20,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionSize12Align4>(
        type: kUnionSize12Align4_Type, offsetOld: 4, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 16, offsetV1: 32),
  ],
  ctor: Sandwich2._ctor,
);

class Sandwich3 extends $fidl.Struct {
  const Sandwich3({
    @required this.before,
    @required this.theUnion,
    @required this.after,
  });
  Sandwich3.clone(
    Sandwich3 $orig, {
    int before,
    UnionSize24Align8 theUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          theUnion: theUnion ?? $orig.theUnion,
          after: after ?? $orig.after,
        );

  Sandwich3._(List<Object> argv)
      : before = argv[0],
        theUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionSize24Align8 theUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      theUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich3' r'(before: ' +
        before.toString() +
        r', theUnion: ' +
        theUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich3 _ctor(List<Object> argv) => Sandwich3._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich3> kSandwich3_Type = $fidl.StructType<Sandwich3>(
  inlineSizeOld: 40,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionSize24Align8>(
        type: kUnionSize24Align8_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 32, offsetV1: 32),
  ],
  ctor: Sandwich3._ctor,
);

class Sandwich4 extends $fidl.Struct {
  const Sandwich4({
    @required this.before,
    @required this.theUnion,
    @required this.after,
  });
  Sandwich4.clone(
    Sandwich4 $orig, {
    int before,
    UnionSize36Align4 theUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          theUnion: theUnion ?? $orig.theUnion,
          after: after ?? $orig.after,
        );

  Sandwich4._(List<Object> argv)
      : before = argv[0],
        theUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionSize36Align4 theUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      theUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich4' r'(before: ' +
        before.toString() +
        r', theUnion: ' +
        theUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich4 _ctor(List<Object> argv) => Sandwich4._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich4> kSandwich4_Type = $fidl.StructType<Sandwich4>(
  inlineSizeOld: 44,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionSize36Align4>(
        type: kUnionSize36Align4_Type, offsetOld: 4, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 40, offsetV1: 32),
  ],
  ctor: Sandwich4._ctor,
);

class Sandwich5 extends $fidl.Struct {
  const Sandwich5({
    @required this.before,
    @required this.unionOfUnion,
    @required this.after,
  });
  Sandwich5.clone(
    Sandwich5 $orig, {
    int before,
    UnionOfUnion unionOfUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          unionOfUnion: unionOfUnion ?? $orig.unionOfUnion,
          after: after ?? $orig.after,
        );

  Sandwich5._(List<Object> argv)
      : before = argv[0],
        unionOfUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionOfUnion unionOfUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      unionOfUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich5' r'(before: ' +
        before.toString() +
        r', unionOfUnion: ' +
        unionOfUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich5 _ctor(List<Object> argv) => Sandwich5._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich5> kSandwich5_Type = $fidl.StructType<Sandwich5>(
  inlineSizeOld: 48,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionOfUnion>(
        type: kUnionOfUnion_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 40, offsetV1: 32),
  ],
  ctor: Sandwich5._ctor,
);

class StructSize3Align1 extends $fidl.Struct {
  const StructSize3Align1({
    @required this.threeBytes,
  });
  StructSize3Align1.clone(
    StructSize3Align1 $orig, {
    Uint8List threeBytes,
  }) : this(
          threeBytes: threeBytes ?? $orig.threeBytes,
        );

  StructSize3Align1._(List<Object> argv) : threeBytes = argv[0];
  final Uint8List threeBytes;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructSize3Align1' r'(threeBytes: ' + threeBytes.toString() + r')';
  }

  static StructSize3Align1 _ctor(List<Object> argv) =>
      StructSize3Align1._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructSize3Align1> kStructSize3Align1_Type =
    $fidl.StructType<StructSize3Align1>(
  inlineSizeOld: 3,
  inlineSizeV1: 3,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Uint8List>(
        type: $fidl.ArrayType<Uint8List>(
            element: $fidl.Uint8Type(), elementCount: 3),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: StructSize3Align1._ctor,
);

class StructSize3Align2 extends $fidl.Struct {
  const StructSize3Align2({
    @required this.f1,
    @required this.f2,
  });
  StructSize3Align2.clone(
    StructSize3Align2 $orig, {
    int f1,
    int f2,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
        );

  StructSize3Align2._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1];
  final int f1;
  final int f2;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StructSize3Align2' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r')';
  }

  static StructSize3Align2 _ctor(List<Object> argv) =>
      StructSize3Align2._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructSize3Align2> kStructSize3Align2_Type =
    $fidl.StructType<StructSize3Align2>(
  inlineSizeOld: 4,
  inlineSizeV1: 4,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint16Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 2, offsetV1: 2),
  ],
  ctor: StructSize3Align2._ctor,
);

class Sandwich6 extends $fidl.Struct {
  const Sandwich6({
    @required this.before,
    @required this.theUnion,
    @required this.after,
  });
  Sandwich6.clone(
    Sandwich6 $orig, {
    int before,
    UnionWithVector theUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          theUnion: theUnion ?? $orig.theUnion,
          after: after ?? $orig.after,
        );

  Sandwich6._(List<Object> argv)
      : before = argv[0],
        theUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionWithVector theUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      theUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich6' r'(before: ' +
        before.toString() +
        r', theUnion: ' +
        theUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich6 _ctor(List<Object> argv) => Sandwich6._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich6> kSandwich6_Type = $fidl.StructType<Sandwich6>(
  inlineSizeOld: 40,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionWithVector>(
        type: kUnionWithVector_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 32, offsetV1: 32),
  ],
  ctor: Sandwich6._ctor,
);

class Sandwich7 extends $fidl.Struct {
  const Sandwich7({
    @required this.before,
    this.optSandwich1,
    @required this.after,
  });
  Sandwich7.clone(
    Sandwich7 $orig, {
    int before,
    Sandwich1 optSandwich1,
    int after,
  }) : this(
          before: before ?? $orig.before,
          optSandwich1: optSandwich1 ?? $orig.optSandwich1,
          after: after ?? $orig.after,
        );

  Sandwich7.cloneWithout(
    Sandwich7 $orig, {
    bool optSandwich1,
  }) : this(
          before: $orig.before,
          optSandwich1: optSandwich1 ? null : $orig.optSandwich1,
          after: $orig.after,
        );

  Sandwich7._(List<Object> argv)
      : before = argv[0],
        optSandwich1 = argv[1],
        after = argv[2];
  final int before;
  final Sandwich1 optSandwich1;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      optSandwich1,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich7' r'(before: ' +
        before.toString() +
        r', optSandwich1: ' +
        optSandwich1.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich7 _ctor(List<Object> argv) => Sandwich7._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich7> kSandwich7_Type = $fidl.StructType<Sandwich7>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<Sandwich1>(
        type: $fidl.PointerType<Sandwich1>(element: kSandwich1_Type),
        offsetOld: 8,
        offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 16, offsetV1: 16),
  ],
  ctor: Sandwich7._ctor,
);

class Sandwich8 extends $fidl.Struct {
  const Sandwich8({
    @required this.before,
    @required this.unionOfUnion,
    @required this.after,
  });
  Sandwich8.clone(
    Sandwich8 $orig, {
    int before,
    UnionOfUnion unionOfUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          unionOfUnion: unionOfUnion ?? $orig.unionOfUnion,
          after: after ?? $orig.after,
        );

  Sandwich8._(List<Object> argv)
      : before = argv[0],
        unionOfUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionOfUnion unionOfUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      unionOfUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich8' r'(before: ' +
        before.toString() +
        r', unionOfUnion: ' +
        unionOfUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich8 _ctor(List<Object> argv) => Sandwich8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich8> kSandwich8_Type = $fidl.StructType<Sandwich8>(
  inlineSizeOld: 48,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionOfUnion>(
        type: kUnionOfUnion_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 40, offsetV1: 32),
  ],
  ctor: Sandwich8._ctor,
);

class Regression1 extends $fidl.Struct {
  const Regression1({
    @required this.f1,
    @required this.f2,
    @required this.f3,
    @required this.f4,
    @required this.f5,
    @required this.f6,
  });
  Regression1.clone(
    Regression1 $orig, {
    int f1,
    int f2,
    int f3,
    int f4,
    int f5,
    int f6,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
          f3: f3 ?? $orig.f3,
          f4: f4 ?? $orig.f4,
          f5: f5 ?? $orig.f5,
          f6: f6 ?? $orig.f6,
        );

  Regression1._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1],
        f3 = argv[2],
        f4 = argv[3],
        f5 = argv[4],
        f6 = argv[5];
  final int f1;
  final int f2;
  final int f3;
  final int f4;
  final int f5;
  final int f6;

  @override
  List<Object> get $fields {
    return <Object>[
      f1,
      f2,
      f3,
      f4,
      f5,
      f6,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Regression1' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r', f3: ' +
        f3.toString() +
        r', f4: ' +
        f4.toString() +
        r', f5: ' +
        f5.toString() +
        r', f6: ' +
        f6.toString() +
        r')';
  }

  static Regression1 _ctor(List<Object> argv) => Regression1._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Regression1> kRegression1_Type =
    $fidl.StructType<Regression1>(
  inlineSizeOld: 32,
  inlineSizeV1: 32,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 4, offsetV1: 4),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint16Type(), offsetOld: 10, offsetV1: 10),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 24, offsetV1: 24),
  ],
  ctor: Regression1._ctor,
);

class Regression2 extends $fidl.Struct {
  const Regression2({
    @required this.head,
    @required this.f7,
  });
  Regression2.clone(
    Regression2 $orig, {
    Regression1 head,
    int f7,
  }) : this(
          head: head ?? $orig.head,
          f7: f7 ?? $orig.f7,
        );

  Regression2._(List<Object> argv)
      : head = argv[0],
        f7 = argv[1];
  final Regression1 head;
  final int f7;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Regression2' r'(head: ' +
        head.toString() +
        r', f7: ' +
        f7.toString() +
        r')';
  }

  static Regression2 _ctor(List<Object> argv) => Regression2._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Regression2> kRegression2_Type =
    $fidl.StructType<Regression2>(
  inlineSizeOld: 40,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Regression1>(
        type: kRegression1_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 32, offsetV1: 32),
  ],
  ctor: Regression2._ctor,
);

class Regression3 extends $fidl.Struct {
  const Regression3({
    this.optValue,
  });
  Regression3.clone(
    Regression3 $orig, {
    Regression2 optValue,
  }) : this(
          optValue: optValue ?? $orig.optValue,
        );

  Regression3.cloneWithout(
    Regression3 $orig, {
    bool optValue,
  }) : this(
          optValue: optValue ? null : $orig.optValue,
        );

  Regression3._(List<Object> argv) : optValue = argv[0];
  final Regression2 optValue;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Regression3' r'(optValue: ' + optValue.toString() + r')';
  }

  static Regression3 _ctor(List<Object> argv) => Regression3._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Regression3> kRegression3_Type =
    $fidl.StructType<Regression3>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Regression2>(
        type: $fidl.PointerType<Regression2>(element: kRegression2_Type),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Regression3._ctor,
);

class TableStructWithReservedSandwichStruct extends $fidl.Struct {
  const TableStructWithReservedSandwichStruct({
    @required this.table,
  });
  TableStructWithReservedSandwichStruct.clone(
    TableStructWithReservedSandwichStruct $orig, {
    TableStructWithReservedSandwich table,
  }) : this(
          table: table ?? $orig.table,
        );

  TableStructWithReservedSandwichStruct._(List<Object> argv) : table = argv[0];
  final TableStructWithReservedSandwich table;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TableStructWithReservedSandwichStruct' r'(table: ' +
        table.toString() +
        r')';
  }

  static TableStructWithReservedSandwichStruct _ctor(List<Object> argv) =>
      TableStructWithReservedSandwichStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TableStructWithReservedSandwichStruct>
    kTable_StructWithReservedSandwichStruct_Type =
    $fidl.StructType<TableStructWithReservedSandwichStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<TableStructWithReservedSandwich>(
        type: kTable_StructWithReservedSandwich_Type,
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: TableStructWithReservedSandwichStruct._ctor,
);

class TableStructWithUint32SandwichStruct extends $fidl.Struct {
  const TableStructWithUint32SandwichStruct({
    @required this.table,
  });
  TableStructWithUint32SandwichStruct.clone(
    TableStructWithUint32SandwichStruct $orig, {
    TableStructWithUint32Sandwich table,
  }) : this(
          table: table ?? $orig.table,
        );

  TableStructWithUint32SandwichStruct._(List<Object> argv) : table = argv[0];
  final TableStructWithUint32Sandwich table;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TableStructWithUint32SandwichStruct' r'(table: ' +
        table.toString() +
        r')';
  }

  static TableStructWithUint32SandwichStruct _ctor(List<Object> argv) =>
      TableStructWithUint32SandwichStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TableStructWithUint32SandwichStruct>
    kTable_StructWithUint32SandwichStruct_Type =
    $fidl.StructType<TableStructWithUint32SandwichStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<TableStructWithUint32Sandwich>(
        type: kTable_StructWithUint32Sandwich_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: TableStructWithUint32SandwichStruct._ctor,
);

class TableUnionWithVectorReservedSandwichStruct extends $fidl.Struct {
  const TableUnionWithVectorReservedSandwichStruct({
    @required this.table,
  });
  TableUnionWithVectorReservedSandwichStruct.clone(
    TableUnionWithVectorReservedSandwichStruct $orig, {
    TableUnionWithVectorReservedSandwich table,
  }) : this(
          table: table ?? $orig.table,
        );

  TableUnionWithVectorReservedSandwichStruct._(List<Object> argv)
      : table = argv[0];
  final TableUnionWithVectorReservedSandwich table;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TableUnionWithVectorReservedSandwichStruct' r'(table: ' +
        table.toString() +
        r')';
  }

  static TableUnionWithVectorReservedSandwichStruct _ctor(List<Object> argv) =>
      TableUnionWithVectorReservedSandwichStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TableUnionWithVectorReservedSandwichStruct>
    kTable_UnionWithVector_ReservedSandwichStruct_Type =
    $fidl.StructType<TableUnionWithVectorReservedSandwichStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<TableUnionWithVectorReservedSandwich>(
        type: kTable_UnionWithVector_ReservedSandwich_Type,
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: TableUnionWithVectorReservedSandwichStruct._ctor,
);

class TableUnionWithVectorStructSandwichStruct extends $fidl.Struct {
  const TableUnionWithVectorStructSandwichStruct({
    @required this.table,
  });
  TableUnionWithVectorStructSandwichStruct.clone(
    TableUnionWithVectorStructSandwichStruct $orig, {
    TableUnionWithVectorStructSandwich table,
  }) : this(
          table: table ?? $orig.table,
        );

  TableUnionWithVectorStructSandwichStruct._(List<Object> argv)
      : table = argv[0];
  final TableUnionWithVectorStructSandwich table;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TableUnionWithVectorStructSandwichStruct' r'(table: ' +
        table.toString() +
        r')';
  }

  static TableUnionWithVectorStructSandwichStruct _ctor(List<Object> argv) =>
      TableUnionWithVectorStructSandwichStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TableUnionWithVectorStructSandwichStruct>
    kTable_UnionWithVector_StructSandwichStruct_Type =
    $fidl.StructType<TableUnionWithVectorStructSandwichStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<TableUnionWithVectorStructSandwich>(
        type: kTable_UnionWithVector_StructSandwich_Type,
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: TableUnionWithVectorStructSandwichStruct._ctor,
);

class XUnionWithStructStruct extends $fidl.Struct {
  const XUnionWithStructStruct({
    @required this.xu,
  });
  XUnionWithStructStruct.clone(
    XUnionWithStructStruct $orig, {
    XUnionWithStruct xu,
  }) : this(
          xu: xu ?? $orig.xu,
        );

  XUnionWithStructStruct._(List<Object> argv) : xu = argv[0];
  final XUnionWithStruct xu;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'XUnionWithStructStruct' r'(xu: ' + xu.toString() + r')';
  }

  static XUnionWithStructStruct _ctor(List<Object> argv) =>
      XUnionWithStructStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<XUnionWithStructStruct> kXUnionWithStructStruct_Type =
    $fidl.StructType<XUnionWithStructStruct>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<XUnionWithStruct>(
        type: kXUnionWithStruct_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: XUnionWithStructStruct._ctor,
);

class XUnionWithXUnionStruct extends $fidl.Struct {
  const XUnionWithXUnionStruct({
    @required this.xu,
  });
  XUnionWithXUnionStruct.clone(
    XUnionWithXUnionStruct $orig, {
    XUnionWithXUnion xu,
  }) : this(
          xu: xu ?? $orig.xu,
        );

  XUnionWithXUnionStruct._(List<Object> argv) : xu = argv[0];
  final XUnionWithXUnion xu;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'XUnionWithXUnionStruct' r'(xu: ' + xu.toString() + r')';
  }

  static XUnionWithXUnionStruct _ctor(List<Object> argv) =>
      XUnionWithXUnionStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<XUnionWithXUnionStruct> kXUnionWithXUnionStruct_Type =
    $fidl.StructType<XUnionWithXUnionStruct>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<XUnionWithXUnion>(
        type: kXUnionWithXUnion_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: XUnionWithXUnionStruct._ctor,
);

class Size5Alignment1 extends $fidl.Struct {
  const Size5Alignment1({
    @required this.data,
  });
  Size5Alignment1.clone(
    Size5Alignment1 $orig, {
    Uint8List data,
  }) : this(
          data: data ?? $orig.data,
        );

  Size5Alignment1._(List<Object> argv) : data = argv[0];
  final Uint8List data;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size5Alignment1' r'(data: ' + data.toString() + r')';
  }

  static Size5Alignment1 _ctor(List<Object> argv) => Size5Alignment1._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size5Alignment1> kSize5Alignment1_Type =
    $fidl.StructType<Size5Alignment1>(
  inlineSizeOld: 5,
  inlineSizeV1: 5,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Uint8List>(
        type: $fidl.ArrayType<Uint8List>(
            element: $fidl.Uint8Type(), elementCount: 5),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Size5Alignment1._ctor,
);

class Size5Alignment4 extends $fidl.Struct {
  const Size5Alignment4({
    @required this.four,
    @required this.one,
  });
  Size5Alignment4.clone(
    Size5Alignment4 $orig, {
    int four,
    int one,
  }) : this(
          four: four ?? $orig.four,
          one: one ?? $orig.one,
        );

  Size5Alignment4._(List<Object> argv)
      : four = argv[0],
        one = argv[1];
  final int four;
  final int one;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size5Alignment4' r'(four: ' +
        four.toString() +
        r', one: ' +
        one.toString() +
        r')';
  }

  static Size5Alignment4 _ctor(List<Object> argv) => Size5Alignment4._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size5Alignment4> kSize5Alignment4_Type =
    $fidl.StructType<Size5Alignment4>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 4, offsetV1: 4),
  ],
  ctor: Size5Alignment4._ctor,
);

class Size5Alignment1Vector extends $fidl.Struct {
  const Size5Alignment1Vector({
    @required this.v,
  });
  Size5Alignment1Vector.clone(
    Size5Alignment1Vector $orig, {
    List<Size5Alignment1> v,
  }) : this(
          v: v ?? $orig.v,
        );

  Size5Alignment1Vector._(List<Object> argv) : v = argv[0];
  final List<Size5Alignment1> v;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size5Alignment1Vector' r'(v: ' + v.toString() + r')';
  }

  static Size5Alignment1Vector _ctor(List<Object> argv) =>
      Size5Alignment1Vector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size5Alignment1Vector> kSize5Alignment1Vector_Type =
    $fidl.StructType<Size5Alignment1Vector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<Size5Alignment1>>(
        type: $fidl.VectorType<List<Size5Alignment1>>(
            element: kSize5Alignment1_Type,
            maybeElementCount: null,
            nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Size5Alignment1Vector._ctor,
);

class Size5Alignment4Vector extends $fidl.Struct {
  const Size5Alignment4Vector({
    @required this.v,
  });
  Size5Alignment4Vector.clone(
    Size5Alignment4Vector $orig, {
    List<Size5Alignment4> v,
  }) : this(
          v: v ?? $orig.v,
        );

  Size5Alignment4Vector._(List<Object> argv) : v = argv[0];
  final List<Size5Alignment4> v;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size5Alignment4Vector' r'(v: ' + v.toString() + r')';
  }

  static Size5Alignment4Vector _ctor(List<Object> argv) =>
      Size5Alignment4Vector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size5Alignment4Vector> kSize5Alignment4Vector_Type =
    $fidl.StructType<Size5Alignment4Vector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<Size5Alignment4>>(
        type: $fidl.VectorType<List<Size5Alignment4>>(
            element: kSize5Alignment4_Type,
            maybeElementCount: null,
            nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Size5Alignment4Vector._ctor,
);

class Size5Alignment1Array extends $fidl.Struct {
  const Size5Alignment1Array({
    @required this.a,
  });
  Size5Alignment1Array.clone(
    Size5Alignment1Array $orig, {
    List<Size5Alignment1> a,
  }) : this(
          a: a ?? $orig.a,
        );

  Size5Alignment1Array._(List<Object> argv) : a = argv[0];
  final List<Size5Alignment1> a;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size5Alignment1Array' r'(a: ' + a.toString() + r')';
  }

  static Size5Alignment1Array _ctor(List<Object> argv) =>
      Size5Alignment1Array._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size5Alignment1Array> kSize5Alignment1Array_Type =
    $fidl.StructType<Size5Alignment1Array>(
  inlineSizeOld: 15,
  inlineSizeV1: 15,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<Size5Alignment1>>(
        type: $fidl.ArrayType<List<Size5Alignment1>>(
            element: kSize5Alignment1_Type, elementCount: 3),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Size5Alignment1Array._ctor,
);

class Size5Alignment4Array extends $fidl.Struct {
  const Size5Alignment4Array({
    @required this.a,
  });
  Size5Alignment4Array.clone(
    Size5Alignment4Array $orig, {
    List<Size5Alignment4> a,
  }) : this(
          a: a ?? $orig.a,
        );

  Size5Alignment4Array._(List<Object> argv) : a = argv[0];
  final List<Size5Alignment4> a;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size5Alignment4Array' r'(a: ' + a.toString() + r')';
  }

  static Size5Alignment4Array _ctor(List<Object> argv) =>
      Size5Alignment4Array._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size5Alignment4Array> kSize5Alignment4Array_Type =
    $fidl.StructType<Size5Alignment4Array>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<Size5Alignment4>>(
        type: $fidl.ArrayType<List<Size5Alignment4>>(
            element: kSize5Alignment4_Type, elementCount: 3),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: Size5Alignment4Array._ctor,
);

class ArrayStruct extends $fidl.Struct {
  const ArrayStruct({
    @required this.unions,
    @required this.optionalUnions,
  });
  ArrayStruct.clone(
    ArrayStruct $orig, {
    List<StringUnion> unions,
    List<StringUnion> optionalUnions,
  }) : this(
          unions: unions ?? $orig.unions,
          optionalUnions: optionalUnions ?? $orig.optionalUnions,
        );

  ArrayStruct._(List<Object> argv)
      : unions = argv[0],
        optionalUnions = argv[1];
  final List<StringUnion> unions;
  final List<StringUnion> optionalUnions;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'ArrayStruct' r'(unions: ' +
        unions.toString() +
        r', optionalUnions: ' +
        optionalUnions.toString() +
        r')';
  }

  static ArrayStruct _ctor(List<Object> argv) => ArrayStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ArrayStruct> kArrayStruct_Type =
    $fidl.StructType<ArrayStruct>(
  inlineSizeOld: 96,
  inlineSizeV1: 144,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<StringUnion>>(
        type: $fidl.ArrayType<List<StringUnion>>(
            element: kStringUnion_Type, elementCount: 3),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<List<StringUnion>>(
        type: $fidl.ArrayType<List<StringUnion>>(
            element:
                $fidl.OptUnionType<StringUnion>(element: kStringUnion_Type),
            elementCount: 3),
        offsetOld: 72,
        offsetV1: 72),
  ],
  ctor: ArrayStruct._ctor,
);

class TransformerEmptyStruct extends $fidl.Struct {
  const TransformerEmptyStruct({
    this.reserved: 0x0,
  });
  TransformerEmptyStruct.clone(
    TransformerEmptyStruct $orig, {
    int reserved,
  }) : this(
          reserved: reserved ?? $orig.reserved,
        );

  TransformerEmptyStruct._(List<Object> argv) : reserved = argv[0];
  final int reserved;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TransformerEmptyStruct' r'(reserved: ' +
        reserved.toString() +
        r')';
  }

  static TransformerEmptyStruct _ctor(List<Object> argv) =>
      TransformerEmptyStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TransformerEmptyStruct> kTransformerEmptyStruct_Type =
    $fidl.StructType<TransformerEmptyStruct>(
  inlineSizeOld: 1,
  inlineSizeV1: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: TransformerEmptyStruct._ctor,
);

class EmptyStructUnionStruct extends $fidl.Struct {
  const EmptyStructUnionStruct({
    @required this.u,
  });
  EmptyStructUnionStruct.clone(
    EmptyStructUnionStruct $orig, {
    EmptyStructUnion u,
  }) : this(
          u: u ?? $orig.u,
        );

  EmptyStructUnionStruct._(List<Object> argv) : u = argv[0];
  final EmptyStructUnion u;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'EmptyStructUnionStruct' r'(u: ' + u.toString() + r')';
  }

  static EmptyStructUnionStruct _ctor(List<Object> argv) =>
      EmptyStructUnionStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<EmptyStructUnionStruct> kEmptyStructUnionStruct_Type =
    $fidl.StructType<EmptyStructUnionStruct>(
  inlineSizeOld: 8,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<EmptyStructUnion>(
        type: kEmptyStructUnion_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: EmptyStructUnionStruct._ctor,
);

class Size8Align8 extends $fidl.Struct {
  const Size8Align8({
    @required this.data,
  });
  Size8Align8.clone(
    Size8Align8 $orig, {
    int data,
  }) : this(
          data: data ?? $orig.data,
        );

  Size8Align8._(List<Object> argv) : data = argv[0];
  final int data;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Size8Align8' r'(data: ' + data.toString() + r')';
  }

  static Size8Align8 _ctor(List<Object> argv) => Size8Align8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Size8Align8> kSize8Align8_Type =
    $fidl.StructType<Size8Align8>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: Size8Align8._ctor,
);

class NoCodingTablesStressor extends $fidl.Struct {
  const NoCodingTablesStressor({
    @required this.f1,
    @required this.f2,
    @required this.u1,
    @required this.f3,
    @required this.f4,
    @required this.u2,
    @required this.f5,
    @required this.f6,
    @required this.u3,
    @required this.f7,
    this.p1,
    @required this.f8,
    this.p2,
    @required this.f9,
  });
  NoCodingTablesStressor.clone(
    NoCodingTablesStressor $orig, {
    int f1,
    int f2,
    UnionSize36Align4 u1,
    int f3,
    int f4,
    UnionSize36Align4 u2,
    int f5,
    int f6,
    UnionSize36Align4 u3,
    int f7,
    Size8Align8 p1,
    int f8,
    Size8Align8 p2,
    int f9,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
          u1: u1 ?? $orig.u1,
          f3: f3 ?? $orig.f3,
          f4: f4 ?? $orig.f4,
          u2: u2 ?? $orig.u2,
          f5: f5 ?? $orig.f5,
          f6: f6 ?? $orig.f6,
          u3: u3 ?? $orig.u3,
          f7: f7 ?? $orig.f7,
          p1: p1 ?? $orig.p1,
          f8: f8 ?? $orig.f8,
          p2: p2 ?? $orig.p2,
          f9: f9 ?? $orig.f9,
        );

  NoCodingTablesStressor.cloneWithout(
    NoCodingTablesStressor $orig, {
    bool p1,
    bool p2,
  }) : this(
          f1: $orig.f1,
          f2: $orig.f2,
          u1: $orig.u1,
          f3: $orig.f3,
          f4: $orig.f4,
          u2: $orig.u2,
          f5: $orig.f5,
          f6: $orig.f6,
          u3: $orig.u3,
          f7: $orig.f7,
          p1: p1 ? null : $orig.p1,
          f8: $orig.f8,
          p2: p2 ? null : $orig.p2,
          f9: $orig.f9,
        );

  NoCodingTablesStressor._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1],
        u1 = argv[2],
        f3 = argv[3],
        f4 = argv[4],
        u2 = argv[5],
        f5 = argv[6],
        f6 = argv[7],
        u3 = argv[8],
        f7 = argv[9],
        p1 = argv[10],
        f8 = argv[11],
        p2 = argv[12],
        f9 = argv[13];
  final int f1;
  final int f2;
  final UnionSize36Align4 u1;
  final int f3;
  final int f4;
  final UnionSize36Align4 u2;
  final int f5;
  final int f6;
  final UnionSize36Align4 u3;
  final int f7;
  final Size8Align8 p1;
  final int f8;
  final Size8Align8 p2;
  final int f9;

  @override
  List<Object> get $fields {
    return <Object>[
      f1,
      f2,
      u1,
      f3,
      f4,
      u2,
      f5,
      f6,
      u3,
      f7,
      p1,
      f8,
      p2,
      f9,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'NoCodingTablesStressor' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r', u1: ' +
        u1.toString() +
        r', f3: ' +
        f3.toString() +
        r', f4: ' +
        f4.toString() +
        r', u2: ' +
        u2.toString() +
        r', f5: ' +
        f5.toString() +
        r', f6: ' +
        f6.toString() +
        r', u3: ' +
        u3.toString() +
        r', f7: ' +
        f7.toString() +
        r', p1: ' +
        p1.toString() +
        r', f8: ' +
        f8.toString() +
        r', p2: ' +
        p2.toString() +
        r', f9: ' +
        f9.toString() +
        r')';
  }

  static NoCodingTablesStressor _ctor(List<Object> argv) =>
      NoCodingTablesStressor._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<NoCodingTablesStressor> kNoCodingTablesStressor_Type =
    $fidl.StructType<NoCodingTablesStressor>(
  inlineSizeOld: 208,
  inlineSizeV1: 160,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint64Type(), offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<UnionSize36Align4>(
        type: kUnionSize36Align4_Type, offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 56, offsetV1: 40),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 64, offsetV1: 48),
    $fidl.MemberType<UnionSize36Align4>(
        type: kUnionSize36Align4_Type, offsetOld: 72, offsetV1: 56),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 112, offsetV1: 80),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 120, offsetV1: 88),
    $fidl.MemberType<UnionSize36Align4>(
        type: kUnionSize36Align4_Type, offsetOld: 128, offsetV1: 96),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 168, offsetV1: 120),
    $fidl.MemberType<Size8Align8>(
        type: $fidl.PointerType<Size8Align8>(element: kSize8Align8_Type),
        offsetOld: 176,
        offsetV1: 128),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 184, offsetV1: 136),
    $fidl.MemberType<Size8Align8>(
        type: $fidl.PointerType<Size8Align8>(element: kSize8Align8_Type),
        offsetOld: 192,
        offsetV1: 144),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 200, offsetV1: 152),
  ],
  ctor: NoCodingTablesStressor._ctor,
);

class OutOfLineSandwich1 extends $fidl.Struct {
  const OutOfLineSandwich1({
    @required this.before,
    @required this.v,
    @required this.after,
  });
  OutOfLineSandwich1.clone(
    OutOfLineSandwich1 $orig, {
    String before,
    List<Sandwich1> v,
    String after,
  }) : this(
          before: before ?? $orig.before,
          v: v ?? $orig.v,
          after: after ?? $orig.after,
        );

  OutOfLineSandwich1._(List<Object> argv)
      : before = argv[0],
        v = argv[1],
        after = argv[2];
  final String before;
  final List<Sandwich1> v;
  final String after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      v,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'OutOfLineSandwich1' r'(before: ' +
        before.toString() +
        r', v: ' +
        v.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static OutOfLineSandwich1 _ctor(List<Object> argv) =>
      OutOfLineSandwich1._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<OutOfLineSandwich1> kOutOfLineSandwich1_Type =
    $fidl.StructType<OutOfLineSandwich1>(
  inlineSizeOld: 48,
  inlineSizeV1: 48,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<List<Sandwich1>>(
        type: $fidl.VectorType<List<Sandwich1>>(
            element: kSandwich1_Type, maybeElementCount: 1, nullable: false),
        offsetOld: 16,
        offsetV1: 16),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 32,
        offsetV1: 32),
  ],
  ctor: OutOfLineSandwich1._ctor,
);

class OutOfLineSandwich1WithOptUnion extends $fidl.Struct {
  const OutOfLineSandwich1WithOptUnion({
    @required this.before,
    @required this.v,
    @required this.after,
  });
  OutOfLineSandwich1WithOptUnion.clone(
    OutOfLineSandwich1WithOptUnion $orig, {
    String before,
    List<Sandwich1WithOptUnion> v,
    String after,
  }) : this(
          before: before ?? $orig.before,
          v: v ?? $orig.v,
          after: after ?? $orig.after,
        );

  OutOfLineSandwich1WithOptUnion._(List<Object> argv)
      : before = argv[0],
        v = argv[1],
        after = argv[2];
  final String before;
  final List<Sandwich1WithOptUnion> v;
  final String after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      v,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'OutOfLineSandwich1WithOptUnion' r'(before: ' +
        before.toString() +
        r', v: ' +
        v.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static OutOfLineSandwich1WithOptUnion _ctor(List<Object> argv) =>
      OutOfLineSandwich1WithOptUnion._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<OutOfLineSandwich1WithOptUnion>
    kOutOfLineSandwich1WithOptUnion_Type =
    $fidl.StructType<OutOfLineSandwich1WithOptUnion>(
  inlineSizeOld: 48,
  inlineSizeV1: 48,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<List<Sandwich1WithOptUnion>>(
        type: $fidl.VectorType<List<Sandwich1WithOptUnion>>(
            element: kSandwich1WithOptUnion_Type,
            maybeElementCount: 1,
            nullable: false),
        offsetOld: 16,
        offsetV1: 16),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 32,
        offsetV1: 32),
  ],
  ctor: OutOfLineSandwich1WithOptUnion._ctor,
);

class Regression4 extends $fidl.Struct {
  const Regression4({
    @required this.f1,
    @required this.f2,
    @required this.s1,
    @required this.f3,
    @required this.f4,
    @required this.f5,
    @required this.f6,
  });
  Regression4.clone(
    Regression4 $orig, {
    int f1,
    int f2,
    StructSize3Align1 s1,
    int f3,
    int f4,
    int f5,
    int f6,
  }) : this(
          f1: f1 ?? $orig.f1,
          f2: f2 ?? $orig.f2,
          s1: s1 ?? $orig.s1,
          f3: f3 ?? $orig.f3,
          f4: f4 ?? $orig.f4,
          f5: f5 ?? $orig.f5,
          f6: f6 ?? $orig.f6,
        );

  Regression4._(List<Object> argv)
      : f1 = argv[0],
        f2 = argv[1],
        s1 = argv[2],
        f3 = argv[3],
        f4 = argv[4],
        f5 = argv[5],
        f6 = argv[6];
  final int f1;
  final int f2;
  final StructSize3Align1 s1;
  final int f3;
  final int f4;
  final int f5;
  final int f6;

  @override
  List<Object> get $fields {
    return <Object>[
      f1,
      f2,
      s1,
      f3,
      f4,
      f5,
      f6,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Regression4' r'(f1: ' +
        f1.toString() +
        r', f2: ' +
        f2.toString() +
        r', s1: ' +
        s1.toString() +
        r', f3: ' +
        f3.toString() +
        r', f4: ' +
        f4.toString() +
        r', f5: ' +
        f5.toString() +
        r', f6: ' +
        f6.toString() +
        r')';
  }

  static Regression4 _ctor(List<Object> argv) => Regression4._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Regression4> kRegression4_Type =
    $fidl.StructType<Regression4>(
  inlineSizeOld: 32,
  inlineSizeV1: 32,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(type: $fidl.Uint32Type(), offsetOld: 4, offsetV1: 4),
    $fidl.MemberType<StructSize3Align1>(
        type: kStructSize3Align1_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 11, offsetV1: 11),
    $fidl.MemberType<int>(
        type: $fidl.Uint16Type(), offsetOld: 12, offsetV1: 12),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offsetOld: 24, offsetV1: 24),
  ],
  ctor: Regression4._ctor,
);

class Sandwich4Align8 extends $fidl.Struct {
  const Sandwich4Align8({
    @required this.sandwich4,
    @required this.alignment8Enforcement,
  });
  Sandwich4Align8.clone(
    Sandwich4Align8 $orig, {
    Sandwich4 sandwich4,
    int alignment8Enforcement,
  }) : this(
          sandwich4: sandwich4 ?? $orig.sandwich4,
          alignment8Enforcement:
              alignment8Enforcement ?? $orig.alignment8Enforcement,
        );

  Sandwich4Align8._(List<Object> argv)
      : sandwich4 = argv[0],
        alignment8Enforcement = argv[1];
  final Sandwich4 sandwich4;
  final int alignment8Enforcement;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich4Align8' r'(sandwich4: ' +
        sandwich4.toString() +
        r', alignment8Enforcement: ' +
        alignment8Enforcement.toString() +
        r')';
  }

  static Sandwich4Align8 _ctor(List<Object> argv) => Sandwich4Align8._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich4Align8> kSandwich4Align8_Type =
    $fidl.StructType<Sandwich4Align8>(
  inlineSizeOld: 56,
  inlineSizeV1: 48,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Sandwich4>(
        type: kSandwich4_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(
        type: $fidl.Uint64Type(), offsetOld: 48, offsetV1: 40),
  ],
  ctor: Sandwich4Align8._ctor,
);

class Sandwich4Align8WithPointer extends $fidl.Struct {
  const Sandwich4Align8WithPointer({
    @required this.sandwich4,
    this.alignment8Enforcement,
  });
  Sandwich4Align8WithPointer.clone(
    Sandwich4Align8WithPointer $orig, {
    Sandwich4 sandwich4,
    Size8Align8 alignment8Enforcement,
  }) : this(
          sandwich4: sandwich4 ?? $orig.sandwich4,
          alignment8Enforcement:
              alignment8Enforcement ?? $orig.alignment8Enforcement,
        );

  Sandwich4Align8WithPointer.cloneWithout(
    Sandwich4Align8WithPointer $orig, {
    bool alignment8Enforcement,
  }) : this(
          sandwich4: $orig.sandwich4,
          alignment8Enforcement:
              alignment8Enforcement ? null : $orig.alignment8Enforcement,
        );

  Sandwich4Align8WithPointer._(List<Object> argv)
      : sandwich4 = argv[0],
        alignment8Enforcement = argv[1];
  final Sandwich4 sandwich4;
  final Size8Align8 alignment8Enforcement;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich4Align8WithPointer' r'(sandwich4: ' +
        sandwich4.toString() +
        r', alignment8Enforcement: ' +
        alignment8Enforcement.toString() +
        r')';
  }

  static Sandwich4Align8WithPointer _ctor(List<Object> argv) =>
      Sandwich4Align8WithPointer._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich4Align8WithPointer>
    kSandwich4Align8WithPointer_Type =
    $fidl.StructType<Sandwich4Align8WithPointer>(
  inlineSizeOld: 56,
  inlineSizeV1: 48,
  members: <$fidl.MemberType>[
    $fidl.MemberType<Sandwich4>(
        type: kSandwich4_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<Size8Align8>(
        type: $fidl.PointerType<Size8Align8>(element: kSize8Align8_Type),
        offsetOld: 48,
        offsetV1: 40),
  ],
  ctor: Sandwich4Align8WithPointer._ctor,
);

class Sandwich9 extends $fidl.Struct {
  const Sandwich9({
    @required this.before,
    @required this.theUnion,
    @required this.after,
  });
  Sandwich9.clone(
    Sandwich9 $orig, {
    int before,
    UnionWithVectorOfVectors theUnion,
    int after,
  }) : this(
          before: before ?? $orig.before,
          theUnion: theUnion ?? $orig.theUnion,
          after: after ?? $orig.after,
        );

  Sandwich9._(List<Object> argv)
      : before = argv[0],
        theUnion = argv[1],
        after = argv[2];
  final int before;
  final UnionWithVectorOfVectors theUnion;
  final int after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      theUnion,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Sandwich9' r'(before: ' +
        before.toString() +
        r', theUnion: ' +
        theUnion.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static Sandwich9 _ctor(List<Object> argv) => Sandwich9._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Sandwich9> kSandwich9_Type = $fidl.StructType<Sandwich9>(
  inlineSizeOld: 40,
  inlineSizeV1: 40,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint16Type(), offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<UnionWithVectorOfVectors>(
        type: kUnionWithVectorOfVectors_Type, offsetOld: 8, offsetV1: 8),
    $fidl.MemberType<int>(
        type: $fidl.Uint16Type(), offsetOld: 32, offsetV1: 32),
  ],
  ctor: Sandwich9._ctor,
);

class SimpleTableArrayStruct extends $fidl.Struct {
  const SimpleTableArrayStruct({
    @required this.theArray,
  });
  SimpleTableArrayStruct.clone(
    SimpleTableArrayStruct $orig, {
    List<TransformerSimpleTable> theArray,
  }) : this(
          theArray: theArray ?? $orig.theArray,
        );

  SimpleTableArrayStruct._(List<Object> argv) : theArray = argv[0];
  final List<TransformerSimpleTable> theArray;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'SimpleTableArrayStruct' r'(theArray: ' +
        theArray.toString() +
        r')';
  }

  static SimpleTableArrayStruct _ctor(List<Object> argv) =>
      SimpleTableArrayStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<SimpleTableArrayStruct> kSimpleTableArrayStruct_Type =
    $fidl.StructType<SimpleTableArrayStruct>(
  inlineSizeOld: 32,
  inlineSizeV1: 32,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<TransformerSimpleTable>>(
        type: $fidl.ArrayType<List<TransformerSimpleTable>>(
            element: kTransformerSimpleTable_Type, elementCount: 2),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: SimpleTableArrayStruct._ctor,
);

class StringUnionVector extends $fidl.Struct {
  const StringUnionVector({
    @required this.theVector,
  });
  StringUnionVector.clone(
    StringUnionVector $orig, {
    List<StringUnion> theVector,
  }) : this(
          theVector: theVector ?? $orig.theVector,
        );

  StringUnionVector._(List<Object> argv) : theVector = argv[0];
  final List<StringUnion> theVector;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'StringUnionVector' r'(theVector: ' + theVector.toString() + r')';
  }

  static StringUnionVector _ctor(List<Object> argv) =>
      StringUnionVector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StringUnionVector> kStringUnionVector_Type =
    $fidl.StructType<StringUnionVector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <$fidl.MemberType>[
    $fidl.MemberType<List<StringUnion>>(
        type: $fidl.VectorType<List<StringUnion>>(
            element:
                $fidl.OptUnionType<StringUnion>(element: kStringUnion_Type),
            maybeElementCount: 3,
            nullable: false),
        offsetOld: 0,
        offsetV1: 0),
  ],
  ctor: StringUnionVector._ctor,
);

class LaunchInfo extends $fidl.Struct {
  const LaunchInfo({
    @required this.url,
    this.arguments,
    this.out,
    this.err,
    @required this.directoryRequest,
    this.flatNamespace,
    this.additionalServices,
  });
  LaunchInfo.clone(
    LaunchInfo $orig, {
    String url,
    List<String> arguments,
    TransformerEmptyStruct out,
    TransformerEmptyStruct err,
    int directoryRequest,
    TransformerEmptyStruct flatNamespace,
    TransformerEmptyStruct additionalServices,
  }) : this(
          url: url ?? $orig.url,
          arguments: arguments ?? $orig.arguments,
          out: out ?? $orig.out,
          err: err ?? $orig.err,
          directoryRequest: directoryRequest ?? $orig.directoryRequest,
          flatNamespace: flatNamespace ?? $orig.flatNamespace,
          additionalServices: additionalServices ?? $orig.additionalServices,
        );

  LaunchInfo.cloneWithout(
    LaunchInfo $orig, {
    bool arguments,
    bool out,
    bool err,
    bool flatNamespace,
    bool additionalServices,
  }) : this(
          url: $orig.url,
          arguments: arguments ? null : $orig.arguments,
          out: out ? null : $orig.out,
          err: err ? null : $orig.err,
          directoryRequest: $orig.directoryRequest,
          flatNamespace: flatNamespace ? null : $orig.flatNamespace,
          additionalServices:
              additionalServices ? null : $orig.additionalServices,
        );

  LaunchInfo._(List<Object> argv)
      : url = argv[0],
        arguments = argv[1],
        out = argv[2],
        err = argv[3],
        directoryRequest = argv[4],
        flatNamespace = argv[5],
        additionalServices = argv[6];
  final String url;
  final List<String> arguments;
  final TransformerEmptyStruct out;
  final TransformerEmptyStruct err;
  final int directoryRequest;
  final TransformerEmptyStruct flatNamespace;
  final TransformerEmptyStruct additionalServices;

  @override
  List<Object> get $fields {
    return <Object>[
      url,
      arguments,
      out,
      err,
      directoryRequest,
      flatNamespace,
      additionalServices,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'LaunchInfo' r'(url: ' +
        url.toString() +
        r', arguments: ' +
        arguments.toString() +
        r', out: ' +
        out.toString() +
        r', err: ' +
        err.toString() +
        r', directoryRequest: ' +
        directoryRequest.toString() +
        r', flatNamespace: ' +
        flatNamespace.toString() +
        r', additionalServices: ' +
        additionalServices.toString() +
        r')';
  }

  static LaunchInfo _ctor(List<Object> argv) => LaunchInfo._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<LaunchInfo> kLaunchInfo_Type =
    $fidl.StructType<LaunchInfo>(
  inlineSizeOld: 72,
  inlineSizeV1: 72,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: 200, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<List<String>>(
        type: $fidl.VectorType<List<String>>(
            element: $fidl.StringType(maybeElementCount: null, nullable: false),
            maybeElementCount: null,
            nullable: true),
        offsetOld: 16,
        offsetV1: 16),
    $fidl.MemberType<TransformerEmptyStruct>(
        type: $fidl.PointerType<TransformerEmptyStruct>(
            element: kTransformerEmptyStruct_Type),
        offsetOld: 32,
        offsetV1: 32),
    $fidl.MemberType<TransformerEmptyStruct>(
        type: $fidl.PointerType<TransformerEmptyStruct>(
            element: kTransformerEmptyStruct_Type),
        offsetOld: 40,
        offsetV1: 40),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 48, offsetV1: 48),
    $fidl.MemberType<TransformerEmptyStruct>(
        type: $fidl.PointerType<TransformerEmptyStruct>(
            element: kTransformerEmptyStruct_Type),
        offsetOld: 56,
        offsetV1: 56),
    $fidl.MemberType<TransformerEmptyStruct>(
        type: $fidl.PointerType<TransformerEmptyStruct>(
            element: kTransformerEmptyStruct_Type),
        offsetOld: 64,
        offsetV1: 64),
  ],
  ctor: LaunchInfo._ctor,
);

class CreateComponentRequest extends $fidl.Struct {
  const CreateComponentRequest({
    @required this.launchInfo,
    @required this.controller,
  });
  CreateComponentRequest.clone(
    CreateComponentRequest $orig, {
    LaunchInfo launchInfo,
    int controller,
  }) : this(
          launchInfo: launchInfo ?? $orig.launchInfo,
          controller: controller ?? $orig.controller,
        );

  CreateComponentRequest._(List<Object> argv)
      : launchInfo = argv[0],
        controller = argv[1];
  final LaunchInfo launchInfo;
  final int controller;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'CreateComponentRequest' r'(launchInfo: ' +
        launchInfo.toString() +
        r', controller: ' +
        controller.toString() +
        r')';
  }

  static CreateComponentRequest _ctor(List<Object> argv) =>
      CreateComponentRequest._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<CreateComponentRequest> kCreateComponentRequest_Type =
    $fidl.StructType<CreateComponentRequest>(
  inlineSizeOld: 80,
  inlineSizeV1: 80,
  members: <$fidl.MemberType>[
    $fidl.MemberType<LaunchInfo>(
        type: kLaunchInfo_Type, offsetOld: 0, offsetV1: 0),
    $fidl.MemberType<int>(
        type: $fidl.Uint32Type(), offsetOld: 72, offsetV1: 72),
  ],
  ctor: CreateComponentRequest._ctor,
);

class Int64Struct extends $fidl.Struct {
  const Int64Struct({
    @required this.x,
  });
  Int64Struct.clone(
    Int64Struct $orig, {
    int x,
  }) : this(
          x: x ?? $orig.x,
        );

  Int64Struct._(List<Object> argv) : x = argv[0];
  final int x;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Int64Struct' r'(x: ' + x.toString() + r')';
  }

  static Int64Struct _ctor(List<Object> argv) => Int64Struct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Int64Struct> kInt64Struct_Type =
    $fidl.StructType<Int64Struct>(
  inlineSizeOld: 8,
  inlineSizeV1: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offsetOld: 0, offsetV1: 0),
  ],
  ctor: Int64Struct._ctor,
);

class TestInlineXUnionInStruct extends $fidl.Struct {
  const TestInlineXUnionInStruct({
    @required this.before,
    @required this.xu,
    @required this.after,
  });
  TestInlineXUnionInStruct.clone(
    TestInlineXUnionInStruct $orig, {
    String before,
    SampleXUnion xu,
    String after,
  }) : this(
          before: before ?? $orig.before,
          xu: xu ?? $orig.xu,
          after: after ?? $orig.after,
        );

  TestInlineXUnionInStruct._(List<Object> argv)
      : before = argv[0],
        xu = argv[1],
        after = argv[2];
  final String before;
  final SampleXUnion xu;
  final String after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      xu,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TestInlineXUnionInStruct' r'(before: ' +
        before.toString() +
        r', xu: ' +
        xu.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static TestInlineXUnionInStruct _ctor(List<Object> argv) =>
      TestInlineXUnionInStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TestInlineXUnionInStruct>
    kTestInlineXUnionInStruct_Type = $fidl.StructType<TestInlineXUnionInStruct>(
  inlineSizeOld: 56,
  inlineSizeV1: 56,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<SampleXUnion>(
        type: kSampleXUnion_Type, offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 40,
        offsetV1: 40),
  ],
  ctor: TestInlineXUnionInStruct._ctor,
);

class TestOptionalXUnionInStruct extends $fidl.Struct {
  const TestOptionalXUnionInStruct({
    @required this.before,
    this.xu,
    @required this.after,
  });
  TestOptionalXUnionInStruct.clone(
    TestOptionalXUnionInStruct $orig, {
    String before,
    SampleXUnion xu,
    String after,
  }) : this(
          before: before ?? $orig.before,
          xu: xu ?? $orig.xu,
          after: after ?? $orig.after,
        );

  TestOptionalXUnionInStruct.cloneWithout(
    TestOptionalXUnionInStruct $orig, {
    bool xu,
  }) : this(
          before: $orig.before,
          xu: xu ? null : $orig.xu,
          after: $orig.after,
        );

  TestOptionalXUnionInStruct._(List<Object> argv)
      : before = argv[0],
        xu = argv[1],
        after = argv[2];
  final String before;
  final SampleXUnion xu;
  final String after;

  @override
  List<Object> get $fields {
    return <Object>[
      before,
      xu,
      after,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TestOptionalXUnionInStruct' r'(before: ' +
        before.toString() +
        r', xu: ' +
        xu.toString() +
        r', after: ' +
        after.toString() +
        r')';
  }

  static TestOptionalXUnionInStruct _ctor(List<Object> argv) =>
      TestOptionalXUnionInStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TestOptionalXUnionInStruct>
    kTestOptionalXUnionInStruct_Type =
    $fidl.StructType<TestOptionalXUnionInStruct>(
  inlineSizeOld: 56,
  inlineSizeV1: 56,
  members: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 0,
        offsetV1: 0),
    $fidl.MemberType<SampleXUnion>(
        type: kSampleXUnion_OptType, offsetOld: 16, offsetV1: 16),
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offsetOld: 40,
        offsetV1: 40),
  ],
  ctor: TestOptionalXUnionInStruct._ctor,
);

class TestStrictXUnionInStruct extends $fidl.Struct {
  const TestStrictXUnionInStruct({
    @required this.xu,
  });
  TestStrictXUnionInStruct.clone(
    TestStrictXUnionInStruct $orig, {
    SampleStrictXUnion xu,
  }) : this(
          xu: xu ?? $orig.xu,
        );

  TestStrictXUnionInStruct._(List<Object> argv) : xu = argv[0];
  final SampleStrictXUnion xu;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TestStrictXUnionInStruct' r'(xu: ' + xu.toString() + r')';
  }

  static TestStrictXUnionInStruct _ctor(List<Object> argv) =>
      TestStrictXUnionInStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TestStrictXUnionInStruct>
    kTestStrictXUnionInStruct_Type = $fidl.StructType<TestStrictXUnionInStruct>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<SampleStrictXUnion>(
        type: kSampleStrictXUnion_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: TestStrictXUnionInStruct._ctor,
);

class TestFlexibleXUnionInStruct extends $fidl.Struct {
  const TestFlexibleXUnionInStruct({
    @required this.xu,
  });
  TestFlexibleXUnionInStruct.clone(
    TestFlexibleXUnionInStruct $orig, {
    SampleXUnion xu,
  }) : this(
          xu: xu ?? $orig.xu,
        );

  TestFlexibleXUnionInStruct._(List<Object> argv) : xu = argv[0];
  final SampleXUnion xu;

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

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'TestFlexibleXUnionInStruct' r'(xu: ' + xu.toString() + r')';
  }

  static TestFlexibleXUnionInStruct _ctor(List<Object> argv) =>
      TestFlexibleXUnionInStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<TestFlexibleXUnionInStruct>
    kTestFlexibleXUnionInStruct_Type =
    $fidl.StructType<TestFlexibleXUnionInStruct>(
  inlineSizeOld: 24,
  inlineSizeV1: 24,
  members: <$fidl.MemberType>[
    $fidl.MemberType<SampleXUnion>(
        type: kSampleXUnion_Type, offsetOld: 0, offsetV1: 0),
  ],
  ctor: TestFlexibleXUnionInStruct._ctor,
);

class XUnionInTable extends $fidl.Table {
  const XUnionInTable({
    this.before,
    this.xu,
    this.after,
  });

  XUnionInTable._(Map<int, dynamic> argv)
      : before = argv[1],
        xu = argv[2],
        after = argv[3];
  final String before;
  final SampleXUnion xu;
  final String after;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: before,
      2: xu,
      3: after,
    };
  }

  static XUnionInTable _ctor(Map<int, dynamic> argv) => XUnionInTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<XUnionInTable> kXUnionInTable_Type =
    $fidl.TableType<XUnionInTable>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null, nullable: false),
    2: kSampleXUnion_Type,
    3: $fidl.StringType(maybeElementCount: null, nullable: false),
  },
  ctor: XUnionInTable._ctor,
);

class SimpleTable extends $fidl.Table {
  const SimpleTable({
    this.x,
    this.y,
  });

  SimpleTable._(Map<int, dynamic> argv)
      : x = argv[1],
        y = argv[5];
  final int x;
  final int y;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: x,
      5: y,
    };
  }

  static SimpleTable _ctor(Map<int, dynamic> argv) => SimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<SimpleTable> kSimpleTable_Type =
    $fidl.TableType<SimpleTable>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    5: $fidl.Int64Type(),
  },
  ctor: SimpleTable._ctor,
);

class TableWithStringAndVector extends $fidl.Table {
  const TableWithStringAndVector({
    this.foo,
    this.bar,
    this.baz,
  });

  TableWithStringAndVector._(Map<int, dynamic> argv)
      : foo = argv[1],
        bar = argv[2],
        baz = argv[3];
  final String foo;
  final int bar;
  final Uint8List baz;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: foo,
      2: bar,
      3: baz,
    };
  }

  static TableWithStringAndVector _ctor(Map<int, dynamic> argv) =>
      TableWithStringAndVector._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TableWithStringAndVector> kTableWithStringAndVector_Type =
    $fidl.TableType<TableWithStringAndVector>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null, nullable: false),
    2: $fidl.Int32Type(),
    3: $fidl.VectorType<Uint8List>(
        element: $fidl.Uint8Type(), maybeElementCount: null, nullable: false),
  },
  ctor: TableWithStringAndVector._ctor,
);

class TableWithEmptyStruct extends $fidl.Table {
  const TableWithEmptyStruct({
    this.s,
  });

  TableWithEmptyStruct._(Map<int, dynamic> argv) : s = argv[1];
  final EmptyStruct s;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: s,
    };
  }

  static TableWithEmptyStruct _ctor(Map<int, dynamic> argv) =>
      TableWithEmptyStruct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TableWithEmptyStruct> kTableWithEmptyStruct_Type =
    $fidl.TableType<TableWithEmptyStruct>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: kEmptyStruct_Type,
  },
  ctor: TableWithEmptyStruct._ctor,
);

class TableStructWithReservedSandwich extends $fidl.Table {
  const TableStructWithReservedSandwich({
    this.s1,
    this.s2,
  });

  TableStructWithReservedSandwich._(Map<int, dynamic> argv)
      : s1 = argv[2],
        s2 = argv[3];
  final StructSize3Align1 s1;
  final StructSize3Align1 s2;

  @override
  Map<int, dynamic> get $fields {
    return {
      2: s1,
      3: s2,
    };
  }

  static TableStructWithReservedSandwich _ctor(Map<int, dynamic> argv) =>
      TableStructWithReservedSandwich._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TableStructWithReservedSandwich>
    kTable_StructWithReservedSandwich_Type =
    $fidl.TableType<TableStructWithReservedSandwich>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    2: kStructSize3Align1_Type,
    3: kStructSize3Align1_Type,
  },
  ctor: TableStructWithReservedSandwich._ctor,
);

class TableStructWithUint32Sandwich extends $fidl.Table {
  const TableStructWithUint32Sandwich({
    this.i,
    this.s1,
    this.s2,
    this.i2,
  });

  TableStructWithUint32Sandwich._(Map<int, dynamic> argv)
      : i = argv[1],
        s1 = argv[2],
        s2 = argv[3],
        i2 = argv[4];
  final int i;
  final StructSize3Align1 s1;
  final StructSize3Align1 s2;
  final int i2;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: i,
      2: s1,
      3: s2,
      4: i2,
    };
  }

  static TableStructWithUint32Sandwich _ctor(Map<int, dynamic> argv) =>
      TableStructWithUint32Sandwich._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TableStructWithUint32Sandwich>
    kTable_StructWithUint32Sandwich_Type =
    $fidl.TableType<TableStructWithUint32Sandwich>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
    2: kStructSize3Align1_Type,
    3: kStructSize3Align1_Type,
    4: $fidl.Uint32Type(),
  },
  ctor: TableStructWithUint32Sandwich._ctor,
);

class TableUnionWithVectorReservedSandwich extends $fidl.Table {
  const TableUnionWithVectorReservedSandwich({
    this.uv,
  });

  TableUnionWithVectorReservedSandwich._(Map<int, dynamic> argv) : uv = argv[2];
  final UnionWithVector uv;

  @override
  Map<int, dynamic> get $fields {
    return {
      2: uv,
    };
  }

  static TableUnionWithVectorReservedSandwich _ctor(Map<int, dynamic> argv) =>
      TableUnionWithVectorReservedSandwich._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TableUnionWithVectorReservedSandwich>
    kTable_UnionWithVector_ReservedSandwich_Type =
    $fidl.TableType<TableUnionWithVectorReservedSandwich>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    2: kUnionWithVector_Type,
  },
  ctor: TableUnionWithVectorReservedSandwich._ctor,
);

class TableUnionWithVectorStructSandwich extends $fidl.Table {
  const TableUnionWithVectorStructSandwich({
    this.s1,
    this.uv,
    this.s2,
  });

  TableUnionWithVectorStructSandwich._(Map<int, dynamic> argv)
      : s1 = argv[1],
        uv = argv[2],
        s2 = argv[3];
  final StructSize3Align1 s1;
  final UnionWithVector uv;
  final StructSize3Align1 s2;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: s1,
      2: uv,
      3: s2,
    };
  }

  static TableUnionWithVectorStructSandwich _ctor(Map<int, dynamic> argv) =>
      TableUnionWithVectorStructSandwich._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TableUnionWithVectorStructSandwich>
    kTable_UnionWithVector_StructSandwich_Type =
    $fidl.TableType<TableUnionWithVectorStructSandwich>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: kStructSize3Align1_Type,
    2: kUnionWithVector_Type,
    3: kStructSize3Align1_Type,
  },
  ctor: TableUnionWithVectorStructSandwich._ctor,
);

class TransformerSimpleTable extends $fidl.Table {
  const TransformerSimpleTable({
    this.value,
  });

  TransformerSimpleTable._(Map<int, dynamic> argv) : value = argv[1];
  final int value;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: value,
    };
  }

  static TransformerSimpleTable _ctor(Map<int, dynamic> argv) =>
      TransformerSimpleTable._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<TransformerSimpleTable> kTransformerSimpleTable_Type =
    $fidl.TableType<TransformerSimpleTable>(
  inlineSizeOld: 16,
  inlineSizeV1: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Uint32Type(),
  },
  ctor: TransformerSimpleTable._ctor,
);

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

abstract class EthernetDevice extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => EthernetDeviceData();
}

class EthernetDeviceData implements $fidl.ServiceData<EthernetDevice> {
  const EthernetDeviceData();

  @override
  String getName() {
    return EthernetDevice.$serviceName;
  }

  @override
  $fidl.AsyncBinding getBinding() {
    return EthernetDeviceBinding();
  }
}

class EthernetDeviceProxy extends $fidl.AsyncProxy<EthernetDevice>
    implements EthernetDevice {
  EthernetDeviceProxy()
      : super($fidl.AsyncProxyController<EthernetDevice>(
            $serviceName: null, $interfaceName: r'EthernetDevice')) {
    ctrl.onResponse = _handleResponse;
  }

  @override
  $fidl.ServiceData get $serviceData => EthernetDeviceData();

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.Message $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }
}

class EthernetDeviceBinding extends $fidl.AsyncBinding<EthernetDevice> {
  EthernetDeviceBinding() : super(r"EthernetDevice");

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for EthernetDeviceBinding');
    }
  }
}
