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

library fidl_fidl_test_union_async;

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

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

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

enum PizzaOrPastaTag {
  pizza, // 0x1
  pasta, // 0x2
}

const Map<int, PizzaOrPastaTag> _PizzaOrPastaTag_map = {
  1: PizzaOrPastaTag.pizza,
  2: PizzaOrPastaTag.pasta,
};

class PizzaOrPasta extends $fidl.XUnion {
  const PizzaOrPasta.withPizza(Pizza value)
      : _ordinal = 1,
        _data = value;

  const PizzaOrPasta.withPasta(Pasta value)
      : _ordinal = 2,
        _data = value;

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

  final int _ordinal;
  final _data;

  PizzaOrPastaTag get $tag => _PizzaOrPastaTag_map[_ordinal]!;

  Pizza? get pizza {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  Pasta? get pasta {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'PizzaOrPasta.pizza(' + pizza.toString() + ')';
      case 2:
        return r'PizzaOrPasta.pasta(' + pasta.toString() + ')';
      default:
        return r'PizzaOrPasta.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<PizzaOrPasta> kPizzaOrPasta_Type =
    $fidl.UnionType<PizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    2: kPasta_Type,
  },
  ctor: PizzaOrPasta._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<PizzaOrPasta> kPizzaOrPasta_OptType =
    $fidl.NullableUnionType<PizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    2: kPasta_Type,
  },
  ctor: PizzaOrPasta._ctor,
  flexible: false,
  resource: false,
);

enum ExplicitPizzaOrPastaTag {
  pizza, // 0x1
  pasta, // 0x4
}

const Map<int, ExplicitPizzaOrPastaTag> _ExplicitPizzaOrPastaTag_map = {
  1: ExplicitPizzaOrPastaTag.pizza,
  4: ExplicitPizzaOrPastaTag.pasta,
};

class ExplicitPizzaOrPasta extends $fidl.XUnion {
  const ExplicitPizzaOrPasta.withPizza(Pizza value)
      : _ordinal = 1,
        _data = value;

  const ExplicitPizzaOrPasta.withPasta(Pasta value)
      : _ordinal = 4,
        _data = value;

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

  final int _ordinal;
  final _data;

  ExplicitPizzaOrPastaTag get $tag => _ExplicitPizzaOrPastaTag_map[_ordinal]!;

  Pizza? get pizza {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  Pasta? get pasta {
    if (_ordinal != 4) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 4:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'ExplicitPizzaOrPasta.pizza(' + pizza.toString() + ')';
      case 4:
        return r'ExplicitPizzaOrPasta.pasta(' + pasta.toString() + ')';
      default:
        return r'ExplicitPizzaOrPasta.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExplicitPizzaOrPasta> kExplicitPizzaOrPasta_Type =
    $fidl.UnionType<ExplicitPizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    4: kPasta_Type,
  },
  ctor: ExplicitPizzaOrPasta._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExplicitPizzaOrPasta>
    kExplicitPizzaOrPasta_OptType =
    $fidl.NullableUnionType<ExplicitPizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    4: kPasta_Type,
  },
  ctor: ExplicitPizzaOrPasta._ctor,
  flexible: false,
  resource: false,
);

enum FlexiblePizzaOrPastaTag {
  $unknown,
  pizza, // 0x1
  pasta, // 0x2
}

const Map<int, FlexiblePizzaOrPastaTag> _FlexiblePizzaOrPastaTag_map = {
  1: FlexiblePizzaOrPastaTag.pizza,
  2: FlexiblePizzaOrPastaTag.pasta,
};

class FlexiblePizzaOrPasta extends $fidl.XUnion {
  const FlexiblePizzaOrPasta.withPizza(Pizza value)
      : _ordinal = 1,
        _data = value;

  const FlexiblePizzaOrPasta.withPasta(Pasta value)
      : _ordinal = 2,
        _data = value;
  const FlexiblePizzaOrPasta.with$UnknownData(
      this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  FlexiblePizzaOrPastaTag get $tag =>
      _FlexiblePizzaOrPastaTag_map[_ordinal] ??
      FlexiblePizzaOrPastaTag.$unknown;

  Pizza? get pizza {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  Pasta? get pasta {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'FlexiblePizzaOrPasta.pizza(' + pizza.toString() + ')';
      case 2:
        return r'FlexiblePizzaOrPasta.pasta(' + pasta.toString() + ')';
      default:
        return r'FlexiblePizzaOrPasta.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FlexiblePizzaOrPasta> kFlexiblePizzaOrPasta_Type =
    $fidl.UnionType<FlexiblePizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    2: kPasta_Type,
  },
  ctor: FlexiblePizzaOrPasta._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<FlexiblePizzaOrPasta>
    kFlexiblePizzaOrPasta_OptType =
    $fidl.NullableUnionType<FlexiblePizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    2: kPasta_Type,
  },
  ctor: FlexiblePizzaOrPasta._ctor,
  flexible: true,
  resource: false,
);

enum StrictPizzaOrPastaTag {
  pizza, // 0x1
  pasta, // 0x2
}

const Map<int, StrictPizzaOrPastaTag> _StrictPizzaOrPastaTag_map = {
  1: StrictPizzaOrPastaTag.pizza,
  2: StrictPizzaOrPastaTag.pasta,
};

class StrictPizzaOrPasta extends $fidl.XUnion {
  const StrictPizzaOrPasta.withPizza(Pizza value)
      : _ordinal = 1,
        _data = value;

  const StrictPizzaOrPasta.withPasta(Pasta value)
      : _ordinal = 2,
        _data = value;

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

  final int _ordinal;
  final _data;

  StrictPizzaOrPastaTag get $tag => _StrictPizzaOrPastaTag_map[_ordinal]!;

  Pizza? get pizza {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  Pasta? get pasta {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'StrictPizzaOrPasta.pizza(' + pizza.toString() + ')';
      case 2:
        return r'StrictPizzaOrPasta.pasta(' + pasta.toString() + ')';
      default:
        return r'StrictPizzaOrPasta.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictPizzaOrPasta> kStrictPizzaOrPasta_Type =
    $fidl.UnionType<StrictPizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    2: kPasta_Type,
  },
  ctor: StrictPizzaOrPasta._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictPizzaOrPasta> kStrictPizzaOrPasta_OptType =
    $fidl.NullableUnionType<StrictPizzaOrPasta>(
  members: <int, $fidl.FidlType>{
    1: kPizza_Type,
    2: kPasta_Type,
  },
  ctor: StrictPizzaOrPasta._ctor,
  flexible: false,
  resource: false,
);

enum UnionTag {
  primitive, // 0x1
  stringNeedsConstructor, // 0x2
  vectorStringAlsoNeedsConstructor, // 0x3
}

const Map<int, UnionTag> _UnionTag_map = {
  1: UnionTag.primitive,
  2: UnionTag.stringNeedsConstructor,
  3: UnionTag.vectorStringAlsoNeedsConstructor,
};

class Union extends $fidl.XUnion {
  const Union.withPrimitive(int value)
      : _ordinal = 1,
        _data = value;

  const Union.withStringNeedsConstructor(String value)
      : _ordinal = 2,
        _data = value;

  const Union.withVectorStringAlsoNeedsConstructor(List<String> value)
      : _ordinal = 3,
        _data = value;

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

  final int _ordinal;
  final _data;

  UnionTag get $tag => _UnionTag_map[_ordinal]!;

  int? get primitive {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  String? get stringNeedsConstructor {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  List<String>? get vectorStringAlsoNeedsConstructor {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
      case 3:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'Union.primitive(' + primitive.toString() + ')';
      case 2:
        return r'Union.stringNeedsConstructor(' +
            stringNeedsConstructor.toString() +
            ')';
      case 3:
        return r'Union.vectorStringAlsoNeedsConstructor(' +
            vectorStringAlsoNeedsConstructor.toString() +
            ')';
      default:
        return r'Union.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<Union> kUnion_Type = $fidl.UnionType<Union>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: Union._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<Union> kUnion_OptType =
    $fidl.NullableUnionType<Union>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: Union._ctor,
  flexible: false,
  resource: false,
);

enum FlexibleUnionTag {
  $unknown,
  primitive, // 0x1
  stringNeedsConstructor, // 0x2
  vectorStringAlsoNeedsConstructor, // 0x3
}

const Map<int, FlexibleUnionTag> _FlexibleUnionTag_map = {
  1: FlexibleUnionTag.primitive,
  2: FlexibleUnionTag.stringNeedsConstructor,
  3: FlexibleUnionTag.vectorStringAlsoNeedsConstructor,
};

class FlexibleUnion extends $fidl.XUnion {
  const FlexibleUnion.withPrimitive(int value)
      : _ordinal = 1,
        _data = value;

  const FlexibleUnion.withStringNeedsConstructor(String value)
      : _ordinal = 2,
        _data = value;

  const FlexibleUnion.withVectorStringAlsoNeedsConstructor(List<String> value)
      : _ordinal = 3,
        _data = value;
  const FlexibleUnion.with$UnknownData(this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  FlexibleUnionTag get $tag =>
      _FlexibleUnionTag_map[_ordinal] ?? FlexibleUnionTag.$unknown;

  int? get primitive {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  String? get stringNeedsConstructor {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  List<String>? get vectorStringAlsoNeedsConstructor {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
      case 3:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'FlexibleUnion.primitive(' + primitive.toString() + ')';
      case 2:
        return r'FlexibleUnion.stringNeedsConstructor(' +
            stringNeedsConstructor.toString() +
            ')';
      case 3:
        return r'FlexibleUnion.vectorStringAlsoNeedsConstructor(' +
            vectorStringAlsoNeedsConstructor.toString() +
            ')';
      default:
        return r'FlexibleUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FlexibleUnion> kFlexibleUnion_Type =
    $fidl.UnionType<FlexibleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: FlexibleUnion._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<FlexibleUnion> kFlexibleUnion_OptType =
    $fidl.NullableUnionType<FlexibleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: FlexibleUnion._ctor,
  flexible: true,
  resource: false,
);

enum StrictUnionTag {
  primitive, // 0x1
  stringNeedsConstructor, // 0x2
  vectorStringAlsoNeedsConstructor, // 0x3
}

const Map<int, StrictUnionTag> _StrictUnionTag_map = {
  1: StrictUnionTag.primitive,
  2: StrictUnionTag.stringNeedsConstructor,
  3: StrictUnionTag.vectorStringAlsoNeedsConstructor,
};

class StrictUnion extends $fidl.XUnion {
  const StrictUnion.withPrimitive(int value)
      : _ordinal = 1,
        _data = value;

  const StrictUnion.withStringNeedsConstructor(String value)
      : _ordinal = 2,
        _data = value;

  const StrictUnion.withVectorStringAlsoNeedsConstructor(List<String> value)
      : _ordinal = 3,
        _data = value;

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

  final int _ordinal;
  final _data;

  StrictUnionTag get $tag => _StrictUnionTag_map[_ordinal]!;

  int? get primitive {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  String? get stringNeedsConstructor {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  List<String>? get vectorStringAlsoNeedsConstructor {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
      case 3:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'StrictUnion.primitive(' + primitive.toString() + ')';
      case 2:
        return r'StrictUnion.stringNeedsConstructor(' +
            stringNeedsConstructor.toString() +
            ')';
      case 3:
        return r'StrictUnion.vectorStringAlsoNeedsConstructor(' +
            vectorStringAlsoNeedsConstructor.toString() +
            ')';
      default:
        return r'StrictUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictUnion> kStrictUnion_Type =
    $fidl.UnionType<StrictUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: StrictUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictUnion> kStrictUnion_OptType =
    $fidl.NullableUnionType<StrictUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: StrictUnion._ctor,
  flexible: false,
  resource: false,
);

enum FieldCollisionTag {
  fieldCollisionTag, // 0x1
}

const Map<int, FieldCollisionTag> _FieldCollisionTag_map = {
  1: FieldCollisionTag.fieldCollisionTag,
};

class FieldCollision extends $fidl.XUnion {
  const FieldCollision.withFieldCollisionTag(int value)
      : _ordinal = 1,
        _data = value;

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

  final int _ordinal;
  final _data;

  FieldCollisionTag get $tag => _FieldCollisionTag_map[_ordinal]!;

  int? get fieldCollisionTag {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'FieldCollision.fieldCollisionTag(' +
            fieldCollisionTag.toString() +
            ')';
      default:
        return r'FieldCollision.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FieldCollision> kFieldCollision_Type =
    $fidl.UnionType<FieldCollision>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: FieldCollision._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<FieldCollision> kFieldCollision_OptType =
    $fidl.NullableUnionType<FieldCollision>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: FieldCollision._ctor,
  flexible: false,
  resource: false,
);

enum ExplicitUnionTag {
  primitive, // 0x1
  stringNeedsConstructor, // 0x3
}

const Map<int, ExplicitUnionTag> _ExplicitUnionTag_map = {
  1: ExplicitUnionTag.primitive,
  3: ExplicitUnionTag.stringNeedsConstructor,
};

class ExplicitUnion extends $fidl.XUnion {
  const ExplicitUnion.withPrimitive(int value)
      : _ordinal = 1,
        _data = value;

  const ExplicitUnion.withStringNeedsConstructor(String value)
      : _ordinal = 3,
        _data = value;

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

  final int _ordinal;
  final _data;

  ExplicitUnionTag get $tag => _ExplicitUnionTag_map[_ordinal]!;

  int? get primitive {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  String? get stringNeedsConstructor {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 3:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'ExplicitUnion.primitive(' + primitive.toString() + ')';
      case 3:
        return r'ExplicitUnion.stringNeedsConstructor(' +
            stringNeedsConstructor.toString() +
            ')';
      default:
        return r'ExplicitUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExplicitUnion> kExplicitUnion_Type =
    $fidl.UnionType<ExplicitUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    3: $fidl.StringType(maybeElementCount: null),
  },
  ctor: ExplicitUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExplicitUnion> kExplicitUnion_OptType =
    $fidl.NullableUnionType<ExplicitUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    3: $fidl.StringType(maybeElementCount: null),
  },
  ctor: ExplicitUnion._ctor,
  flexible: false,
  resource: false,
);

enum ReverseOrdinalUnionTag {
  second, // 0x2
  first, // 0x1
}

const Map<int, ReverseOrdinalUnionTag> _ReverseOrdinalUnionTag_map = {
  2: ReverseOrdinalUnionTag.second,
  1: ReverseOrdinalUnionTag.first,
};

class ReverseOrdinalUnion extends $fidl.XUnion {
  const ReverseOrdinalUnion.withSecond(int value)
      : _ordinal = 2,
        _data = value;

  const ReverseOrdinalUnion.withFirst(int value)
      : _ordinal = 1,
        _data = value;

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

  final int _ordinal;
  final _data;

  ReverseOrdinalUnionTag get $tag => _ReverseOrdinalUnionTag_map[_ordinal]!;

  int? get second {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  int? get first {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 2:
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 2:
        return r'ReverseOrdinalUnion.second(' + second.toString() + ')';
      case 1:
        return r'ReverseOrdinalUnion.first(' + first.toString() + ')';
      default:
        return r'ReverseOrdinalUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ReverseOrdinalUnion> kReverseOrdinalUnion_Type =
    $fidl.UnionType<ReverseOrdinalUnion>(
  members: <int, $fidl.FidlType>{
    2: $fidl.Uint32Type(),
    1: $fidl.Uint32Type(),
  },
  ctor: ReverseOrdinalUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ReverseOrdinalUnion>
    kReverseOrdinalUnion_OptType = $fidl.NullableUnionType<ReverseOrdinalUnion>(
  members: <int, $fidl.FidlType>{
    2: $fidl.Uint32Type(),
    1: $fidl.Uint32Type(),
  },
  ctor: ReverseOrdinalUnion._ctor,
  flexible: false,
  resource: false,
);

enum FlexibleFooTag {
  $unknown,
  s, // 0x1
  i, // 0x2
}

const Map<int, FlexibleFooTag> _FlexibleFooTag_map = {
  1: FlexibleFooTag.s,
  2: FlexibleFooTag.i,
};

class FlexibleFoo extends $fidl.XUnion {
  const FlexibleFoo.withS(String value)
      : _ordinal = 1,
        _data = value;

  const FlexibleFoo.withI(int value)
      : _ordinal = 2,
        _data = value;
  const FlexibleFoo.with$UnknownData(this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  FlexibleFooTag get $tag =>
      _FlexibleFooTag_map[_ordinal] ?? FlexibleFooTag.$unknown;

  String? get s {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  int? get i {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'FlexibleFoo.s(' + s.toString() + ')';
      case 2:
        return r'FlexibleFoo.i(' + i.toString() + ')';
      default:
        return r'FlexibleFoo.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FlexibleFoo> kFlexibleFoo_Type =
    $fidl.UnionType<FlexibleFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: FlexibleFoo._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<FlexibleFoo> kFlexibleFoo_OptType =
    $fidl.NullableUnionType<FlexibleFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: FlexibleFoo._ctor,
  flexible: true,
  resource: false,
);

enum StrictFooTag {
  s, // 0x1
  i, // 0x2
}

const Map<int, StrictFooTag> _StrictFooTag_map = {
  1: StrictFooTag.s,
  2: StrictFooTag.i,
};

class StrictFoo extends $fidl.XUnion {
  const StrictFoo.withS(String value)
      : _ordinal = 1,
        _data = value;

  const StrictFoo.withI(int value)
      : _ordinal = 2,
        _data = value;

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

  final int _ordinal;
  final _data;

  StrictFooTag get $tag => _StrictFooTag_map[_ordinal]!;

  String? get s {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  int? get i {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'StrictFoo.s(' + s.toString() + ')';
      case 2:
        return r'StrictFoo.i(' + i.toString() + ')';
      default:
        return r'StrictFoo.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictFoo> kStrictFoo_Type = $fidl.UnionType<StrictFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: StrictFoo._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictFoo> kStrictFoo_OptType =
    $fidl.NullableUnionType<StrictFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: StrictFoo._ctor,
  flexible: false,
  resource: false,
);

enum ExplicitFooTag {
  $unknown,
  s, // 0x2
  i, // 0x1
}

const Map<int, ExplicitFooTag> _ExplicitFooTag_map = {
  2: ExplicitFooTag.s,
  1: ExplicitFooTag.i,
};

class ExplicitFoo extends $fidl.XUnion {
  const ExplicitFoo.withS(String value)
      : _ordinal = 2,
        _data = value;

  const ExplicitFoo.withI(int value)
      : _ordinal = 1,
        _data = value;
  const ExplicitFoo.with$UnknownData(this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  ExplicitFooTag get $tag =>
      _ExplicitFooTag_map[_ordinal] ?? ExplicitFooTag.$unknown;

  String? get s {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  int? get i {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 2:
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 2:
        return r'ExplicitFoo.s(' + s.toString() + ')';
      case 1:
        return r'ExplicitFoo.i(' + i.toString() + ')';
      default:
        return r'ExplicitFoo.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExplicitFoo> kExplicitFoo_Type =
    $fidl.UnionType<ExplicitFoo>(
  members: <int, $fidl.FidlType>{
    2: $fidl.StringType(maybeElementCount: null),
    1: $fidl.Int32Type(),
  },
  ctor: ExplicitFoo._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExplicitFoo> kExplicitFoo_OptType =
    $fidl.NullableUnionType<ExplicitFoo>(
  members: <int, $fidl.FidlType>{
    2: $fidl.StringType(maybeElementCount: null),
    1: $fidl.Int32Type(),
  },
  ctor: ExplicitFoo._ctor,
  flexible: true,
  resource: false,
);

enum ExplicitStrictFooTag {
  s, // 0x3
  i, // 0x2
}

const Map<int, ExplicitStrictFooTag> _ExplicitStrictFooTag_map = {
  3: ExplicitStrictFooTag.s,
  2: ExplicitStrictFooTag.i,
};

class ExplicitStrictFoo extends $fidl.XUnion {
  const ExplicitStrictFoo.withS(String value)
      : _ordinal = 3,
        _data = value;

  const ExplicitStrictFoo.withI(int value)
      : _ordinal = 2,
        _data = value;

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

  final int _ordinal;
  final _data;

  ExplicitStrictFooTag get $tag => _ExplicitStrictFooTag_map[_ordinal]!;

  String? get s {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  int? get i {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 3:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 3:
        return r'ExplicitStrictFoo.s(' + s.toString() + ')';
      case 2:
        return r'ExplicitStrictFoo.i(' + i.toString() + ')';
      default:
        return r'ExplicitStrictFoo.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExplicitStrictFoo> kExplicitStrictFoo_Type =
    $fidl.UnionType<ExplicitStrictFoo>(
  members: <int, $fidl.FidlType>{
    3: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: ExplicitStrictFoo._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExplicitStrictFoo> kExplicitStrictFoo_OptType =
    $fidl.NullableUnionType<ExplicitStrictFoo>(
  members: <int, $fidl.FidlType>{
    3: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: ExplicitStrictFoo._ctor,
  flexible: false,
  resource: false,
);

enum OlderSimpleUnionTag {
  $unknown,
  i, // 0x1
  f, // 0x2
}

const Map<int, OlderSimpleUnionTag> _OlderSimpleUnionTag_map = {
  1: OlderSimpleUnionTag.i,
  2: OlderSimpleUnionTag.f,
};

class OlderSimpleUnion extends $fidl.XUnion {
  const OlderSimpleUnion.withI(int value)
      : _ordinal = 1,
        _data = value;

  const OlderSimpleUnion.withF(double value)
      : _ordinal = 2,
        _data = value;
  const OlderSimpleUnion.with$UnknownData(
      this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  OlderSimpleUnionTag get $tag =>
      _OlderSimpleUnionTag_map[_ordinal] ?? OlderSimpleUnionTag.$unknown;

  int? get i {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  double? get f {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'OlderSimpleUnion.i(' + i.toString() + ')';
      case 2:
        return r'OlderSimpleUnion.f(' + f.toString() + ')';
      default:
        return r'OlderSimpleUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<OlderSimpleUnion> kOlderSimpleUnion_Type =
    $fidl.UnionType<OlderSimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    2: $fidl.Float32Type(),
  },
  ctor: OlderSimpleUnion._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<OlderSimpleUnion> kOlderSimpleUnion_OptType =
    $fidl.NullableUnionType<OlderSimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    2: $fidl.Float32Type(),
  },
  ctor: OlderSimpleUnion._ctor,
  flexible: true,
  resource: false,
);

enum NewerSimpleUnionTag {
  $unknown,
  i, // 0x1
  s, // 0x2
  v, // 0x3
}

const Map<int, NewerSimpleUnionTag> _NewerSimpleUnionTag_map = {
  1: NewerSimpleUnionTag.i,
  2: NewerSimpleUnionTag.s,
  3: NewerSimpleUnionTag.v,
};

class NewerSimpleUnion extends $fidl.XUnion {
  const NewerSimpleUnion.withI(int value)
      : _ordinal = 1,
        _data = value;

  const NewerSimpleUnion.withS(String value)
      : _ordinal = 2,
        _data = value;

  const NewerSimpleUnion.withV(List<String> value)
      : _ordinal = 3,
        _data = value;
  const NewerSimpleUnion.with$UnknownData(
      this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  NewerSimpleUnionTag get $tag =>
      _NewerSimpleUnionTag_map[_ordinal] ?? NewerSimpleUnionTag.$unknown;

  int? get i {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  String? get s {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  List<String>? get v {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
      case 3:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'NewerSimpleUnion.i(' + i.toString() + ')';
      case 2:
        return r'NewerSimpleUnion.s(' + s.toString() + ')';
      case 3:
        return r'NewerSimpleUnion.v(' + v.toString() + ')';
      default:
        return r'NewerSimpleUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<NewerSimpleUnion> kNewerSimpleUnion_Type =
    $fidl.UnionType<NewerSimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: NewerSimpleUnion._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<NewerSimpleUnion> kNewerSimpleUnion_OptType =
    $fidl.NullableUnionType<NewerSimpleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    2: $fidl.StringType(maybeElementCount: null),
    3: $fidl.VectorType<String, List<String>>(
        element: $fidl.StringType(maybeElementCount: null),
        maybeElementCount: null),
  },
  ctor: NewerSimpleUnion._ctor,
  flexible: true,
  resource: false,
);

enum StrictSimpleXUnionTag {
  i, // 0x1
  f, // 0x2
  s, // 0x3
}

const Map<int, StrictSimpleXUnionTag> _StrictSimpleXUnionTag_map = {
  1: StrictSimpleXUnionTag.i,
  2: StrictSimpleXUnionTag.f,
  3: StrictSimpleXUnionTag.s,
};

class StrictSimpleXUnion extends $fidl.XUnion {
  const StrictSimpleXUnion.withI(int value)
      : _ordinal = 1,
        _data = value;

  const StrictSimpleXUnion.withF(double value)
      : _ordinal = 2,
        _data = value;

  const StrictSimpleXUnion.withS(String value)
      : _ordinal = 3,
        _data = value;

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

  final int _ordinal;
  final _data;

  StrictSimpleXUnionTag get $tag => _StrictSimpleXUnionTag_map[_ordinal]!;

  int? get i {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  double? get f {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  String? get s {
    if (_ordinal != 3) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
      case 3:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'StrictSimpleXUnion.i(' + i.toString() + ')';
      case 2:
        return r'StrictSimpleXUnion.f(' + f.toString() + ')';
      case 3:
        return r'StrictSimpleXUnion.s(' + s.toString() + ')';
      default:
        return r'StrictSimpleXUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictSimpleXUnion> kStrictSimpleXUnion_Type =
    $fidl.UnionType<StrictSimpleXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.Float32Type(),
    3: $fidl.StringType(maybeElementCount: null),
  },
  ctor: StrictSimpleXUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictSimpleXUnion> kStrictSimpleXUnion_OptType =
    $fidl.NullableUnionType<StrictSimpleXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
    2: $fidl.Float32Type(),
    3: $fidl.StringType(maybeElementCount: null),
  },
  ctor: StrictSimpleXUnion._ctor,
  flexible: false,
  resource: false,
);

enum XUnionContainingEmptyStructTag {
  $unknown,
  empty, // 0x1
}

const Map<int, XUnionContainingEmptyStructTag>
    _XUnionContainingEmptyStructTag_map = {
  1: XUnionContainingEmptyStructTag.empty,
};

class XUnionContainingEmptyStruct extends $fidl.XUnion {
  const XUnionContainingEmptyStruct.withEmpty(Empty value)
      : _ordinal = 1,
        _data = value;
  const XUnionContainingEmptyStruct.with$UnknownData(
      this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  XUnionContainingEmptyStructTag get $tag =>
      _XUnionContainingEmptyStructTag_map[_ordinal] ??
      XUnionContainingEmptyStructTag.$unknown;

  Empty? get empty {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'XUnionContainingEmptyStruct.empty(' + empty.toString() + ')';
      default:
        return r'XUnionContainingEmptyStruct.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<XUnionContainingEmptyStruct>
    kXUnionContainingEmptyStruct_Type =
    $fidl.UnionType<XUnionContainingEmptyStruct>(
  members: <int, $fidl.FidlType>{
    1: kEmpty_Type,
  },
  ctor: XUnionContainingEmptyStruct._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<XUnionContainingEmptyStruct>
    kXUnionContainingEmptyStruct_OptType =
    $fidl.NullableUnionType<XUnionContainingEmptyStruct>(
  members: <int, $fidl.FidlType>{
    1: kEmpty_Type,
  },
  ctor: XUnionContainingEmptyStruct._ctor,
  flexible: true,
  resource: false,
);

enum StrictBoundedXUnionTag {
  v, // 0x1
}

const Map<int, StrictBoundedXUnionTag> _StrictBoundedXUnionTag_map = {
  1: StrictBoundedXUnionTag.v,
};

class StrictBoundedXUnion extends $fidl.XUnion {
  const StrictBoundedXUnion.withV(Uint8List value)
      : _ordinal = 1,
        _data = value;

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

  final int _ordinal;
  final _data;

  StrictBoundedXUnionTag get $tag => _StrictBoundedXUnionTag_map[_ordinal]!;

  Uint8List? get v {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'StrictBoundedXUnion.v(' + v.toString() + ')';
      default:
        return r'StrictBoundedXUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictBoundedXUnion> kStrictBoundedXUnion_Type =
    $fidl.UnionType<StrictBoundedXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.VectorType<int, Uint8List>(
        element: $fidl.Uint8Type(), maybeElementCount: 10),
  },
  ctor: StrictBoundedXUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictBoundedXUnion>
    kStrictBoundedXUnion_OptType = $fidl.NullableUnionType<StrictBoundedXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.VectorType<int, Uint8List>(
        element: $fidl.Uint8Type(), maybeElementCount: 10),
  },
  ctor: StrictBoundedXUnion._ctor,
  flexible: false,
  resource: false,
);

enum ExplicitXUnionTag {
  $unknown,
  i, // 0x1
  f, // 0x4
}

const Map<int, ExplicitXUnionTag> _ExplicitXUnionTag_map = {
  1: ExplicitXUnionTag.i,
  4: ExplicitXUnionTag.f,
};

class ExplicitXUnion extends $fidl.XUnion {
  const ExplicitXUnion.withI(int value)
      : _ordinal = 1,
        _data = value;

  const ExplicitXUnion.withF(double value)
      : _ordinal = 4,
        _data = value;
  const ExplicitXUnion.with$UnknownData(
      this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  ExplicitXUnionTag get $tag =>
      _ExplicitXUnionTag_map[_ordinal] ?? ExplicitXUnionTag.$unknown;

  int? get i {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  double? get f {
    if (_ordinal != 4) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 4:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'ExplicitXUnion.i(' + i.toString() + ')';
      case 4:
        return r'ExplicitXUnion.f(' + f.toString() + ')';
      default:
        return r'ExplicitXUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExplicitXUnion> kExplicitXUnion_Type =
    $fidl.UnionType<ExplicitXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    4: $fidl.Float32Type(),
  },
  ctor: ExplicitXUnion._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExplicitXUnion> kExplicitXUnion_OptType =
    $fidl.NullableUnionType<ExplicitXUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int64Type(),
    4: $fidl.Float32Type(),
  },
  ctor: ExplicitXUnion._ctor,
  flexible: true,
  resource: false,
);

class Pizza extends $fidl.Struct {
  const Pizza({
    required this.toppings,
  });
  Pizza.clone(
    Pizza $orig, {
    List<String>? toppings,
  }) : this(
          toppings: toppings ?? $orig.toppings,
        );

  final List<String> toppings;

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

  static const $fieldType0 = $fidl.VectorType<String, List<String>>(
      element: $fidl.StringType(maybeElementCount: 16),
      maybeElementCount: null);

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

  @override
  String toString() {
    return r'Pizza' r'(toppings: ' + toppings.toString() + r')';
  }

  static Pizza _structDecode($fidl.Decoder $decoder, int $offset) {
    return Pizza(toppings: $fieldType0.decode($decoder, $offset + 0));
  }
}

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

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

  final String sauce;

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

  static const $fieldType0 = $fidl.StringType(maybeElementCount: 16);

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

  @override
  String toString() {
    return r'Pasta' r'(sauce: ' + sauce.toString() + r')';
  }

  static Pasta _structDecode($fidl.Decoder $decoder, int $offset) {
    return Pasta(sauce: $fieldType0.decode($decoder, $offset + 0));
  }
}

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

class NullableUnionStruct extends $fidl.Struct {
  const NullableUnionStruct({
    this.theUnion,
  });
  NullableUnionStruct.clone(
    NullableUnionStruct $orig, {
    Union? theUnion,
  }) : this(
          theUnion: theUnion ?? $orig.theUnion,
        );

  NullableUnionStruct.cloneWithout(
    NullableUnionStruct $orig, {
    bool theUnion = false,
  }) : this(
          theUnion: theUnion ? null : $orig.theUnion,
        );

  final Union? theUnion;

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

  static const $fieldType0 = kUnion_OptType;

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

  @override
  String toString() {
    return r'NullableUnionStruct' r'(theUnion: ' + theUnion.toString() + r')';
  }

  static NullableUnionStruct _structDecode(
      $fidl.Decoder $decoder, int $offset) {
    return NullableUnionStruct(
        theUnion: $fieldType0.decode($decoder, $offset + 0));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<NullableUnionStruct> kNullableUnionStruct_Type =
    $fidl.StructType<NullableUnionStruct>(
  inlineSize: 24,
  structDecode: NullableUnionStruct._structDecode,
);

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

  final int reserved;

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

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

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

  @override
  String toString() {
    return r'Empty' r'(reserved: ' + reserved.toString() + r')';
  }

  static Empty _structDecode($fidl.Decoder $decoder, int $offset) {
    return Empty(reserved: $fieldType0.decode($decoder, $offset + 0));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Empty> kEmpty_Type = $fidl.StructType<Empty>(
  inlineSize: 1,
  structDecode: Empty._structDecode,
);

class StructWithNullableXUnion extends $fidl.Struct {
  const StructWithNullableXUnion({
    this.x1,
  });
  StructWithNullableXUnion.clone(
    StructWithNullableXUnion $orig, {
    OlderSimpleUnion? x1,
  }) : this(
          x1: x1 ?? $orig.x1,
        );

  StructWithNullableXUnion.cloneWithout(
    StructWithNullableXUnion $orig, {
    bool x1 = false,
  }) : this(
          x1: x1 ? null : $orig.x1,
        );

  final OlderSimpleUnion? x1;

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

  static const $fieldType0 = kOlderSimpleUnion_OptType;

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

  @override
  String toString() {
    return r'StructWithNullableXUnion' r'(x1: ' + x1.toString() + r')';
  }

  static StructWithNullableXUnion _structDecode(
      $fidl.Decoder $decoder, int $offset) {
    return StructWithNullableXUnion(
        x1: $fieldType0.decode($decoder, $offset + 0));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<StructWithNullableXUnion>
    kStructWithNullableXUnion_Type = $fidl.StructType<StructWithNullableXUnion>(
  inlineSize: 24,
  structDecode: StructWithNullableXUnion._structDecode,
);

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

// strictXUnionHenceResponseMayBeStackAllocated: () -> (StrictBoundedXUnion xu)
const int _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal =
    0x747b084a44f0dc3e;
const $fidl.MethodType
    _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type =
    $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<StrictBoundedXUnion>(
        type: kStrictBoundedXUnion_Type, offset: 0),
  ],
  name: r"TestProtocol.StrictXUnionHenceResponseMayBeStackAllocated",
  requestInlineSize: 0,
  responseInlineSize: 24,
);
// flexibleXUnionHenceResponseMustBeHeapAllocated: () -> (OlderSimpleUnion xu)
const int
    _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal =
    0x57615a25c2a785d2;
const $fidl.MethodType
    _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type =
    $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<OlderSimpleUnion>(type: kOlderSimpleUnion_Type, offset: 0),
  ],
  name: r"TestProtocol.FlexibleXUnionHenceResponseMustBeHeapAllocated",
  requestInlineSize: 0,
  responseInlineSize: 24,
);

abstract class TestProtocol {
  $fidl.ServiceData? get $serviceData => TestProtocolData();
  $async.Future<StrictBoundedXUnion>
      strictXUnionHenceResponseMayBeStackAllocated();
  $async.Future<OlderSimpleUnion>
      flexibleXUnionHenceResponseMustBeHeapAllocated();
}

// TODO: Remove ServiceData for non-service
class TestProtocolData implements $fidl.ServiceData<TestProtocol> {
  const TestProtocolData();

  @override
  String getName() {
    return "";
  }

  @override
  $fidl.AsyncBinding getBinding() {
    return TestProtocolBinding();
  }
}

class TestProtocolProxy extends $fidl.AsyncProxy<TestProtocol>
    implements TestProtocol {
  TestProtocolProxy()
      : super($fidl.AsyncProxyController<TestProtocol>(
            $interfaceName: r'TestProtocol')) {
    ctrl.onResponse = _handleResponse;
  }
  @override
  Null get $serviceData => null;

  void _handleEvent($fidl.Message $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;
    }
    switch ($message.ordinal) {
      case _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
        final String _name =
            _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                .name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                  .response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                  .decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
        final String _name =
            _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                .name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                  .response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                  .decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<StrictBoundedXUnion>
      strictXUnionHenceResponseMayBeStackAllocated() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal, 0);
    final $completer = $async.Completer<StrictBoundedXUnion>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<OlderSimpleUnion>
      flexibleXUnionHenceResponseMustBeHeapAllocated() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal,
        0);
    final $completer = $async.Completer<OlderSimpleUnion>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

class TestProtocolBinding extends $fidl.AsyncBinding<TestProtocol> {
  TestProtocolBinding() : super(r"TestProtocol");

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    switch ($message.ordinal) {
      case _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal:
        final String _name =
            _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                .name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<
              StrictBoundedXUnion> $future = $fidl.decodeMessageWithCallback<
                  $async.Future<StrictBoundedXUnion>>(
              $message,
              _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                  .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.strictXUnionHenceResponseMayBeStackAllocated();
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Ordinal,
                $message.txid);
            final List<$fidl.MemberType> $types =
                _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                    .response!;
            $fidl.encodeMessage(
                $encoder,
                _kTestProtocol_StrictXUnionHenceResponseMayBeStackAllocated_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal:
        final String _name =
            _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                .name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<
              OlderSimpleUnion> $future = $fidl.decodeMessageWithCallback<
                  $async.Future<OlderSimpleUnion>>(
              $message,
              _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                  .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.flexibleXUnionHenceResponseMustBeHeapAllocated();
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Ordinal,
                $message.txid);
            final List<$fidl.MemberType> $types =
                _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                    .response!;
            $fidl.encodeMessage(
                $encoder,
                _kTestProtocol_FlexibleXUnionHenceResponseMustBeHeapAllocated_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for TestProtocolBinding');
    }
  }
}
