// Copyright 2018 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.
//
// WARNING: This file is machine generated by fidlgen.

library fidl_test_name;

import 'dart:async';
import 'dart:typed_data';

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

// These imports improve deduplication by making uses of {fidl.dart},
// {fidl_async.dart} and {fidl.dart, fidl_async.dart} generate equivalent
// packages. In AOT, the dead code will be removed by tree shaking.
// ignore: unused_import
import 'fidl_async.dart' as $strongly_connect_async;

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

enum EmptyUnionTag {
}

const Map<int, EmptyUnionTag> _EmptyUnionTag_map = const {
};


class EmptyUnion extends $fidl.XUnion {

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

  final int _ordinal;
  final _data;

  EmptyUnionTag get tag => _EmptyUnionTag_map[_ordinal];



  @override
  String toString() {
    switch (_ordinal) {
      default:
        return null;
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<EmptyUnion> kEmptyUnion_Type = const $fidl.XUnionType<EmptyUnion>(
  encodedSize: 24,
  members: const <int, $fidl.FidlType>{},
  ctor: EmptyUnion._ctor,
);
const $fidl.XUnionType<EmptyUnion> kEmptyUnion_OptType = const $fidl.XUnionType<EmptyUnion>(
encodedSize: 24,
members: const <int, $fidl.FidlType>{},
ctor: EmptyUnion._ctor,
nullable: true,
);

enum OlderSimpleUnionTag {
  i, // 0x3d32b1d7
  f, // 0x5136cf7e
}

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


class OlderSimpleUnion extends $fidl.XUnion {

  const OlderSimpleUnion.withI(int value)
    : _ordinal = 1026732503, _data = value;

  const OlderSimpleUnion.withF(double value)
    : _ordinal = 1362546558, _data = value;

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

  final int _ordinal;
  final _data;

  OlderSimpleUnionTag get tag => _OlderSimpleUnionTag_map[_ordinal];


  int get i {
    if (_ordinal != 1026732503) {
      return null;
    }
    return _data;
  }
  double get f {
    if (_ordinal != 1362546558) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1026732503:
        return 'OlderSimpleUnion.i($i)';
      case 1362546558:
        return 'OlderSimpleUnion.f($f)';
      default:
        return null;
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<OlderSimpleUnion> kOlderSimpleUnion_Type = const $fidl.XUnionType<OlderSimpleUnion>(
  encodedSize: 24,
  members: const <int, $fidl.FidlType>{
    1026732503: const $fidl.Int64Type(),
    1362546558: const $fidl.Float32Type(),
  },
  ctor: OlderSimpleUnion._ctor,
);
const $fidl.XUnionType<OlderSimpleUnion> kOlderSimpleUnion_OptType = const $fidl.XUnionType<OlderSimpleUnion>(
encodedSize: 24,
members: const <int, $fidl.FidlType>{
    1026732503: const $fidl.Int64Type(),
    1362546558: const $fidl.Float32Type(),
  },
ctor: OlderSimpleUnion._ctor,
nullable: true,
);

enum NewerSimpleUnionTag {
  i, // 0x295cbfde
  s, // 0x1c3b9247
  v, // 0x6c38b28f
}

const Map<int, NewerSimpleUnionTag> _NewerSimpleUnionTag_map = const {
  693944286: NewerSimpleUnionTag.i,
  473666119: NewerSimpleUnionTag.s,
  1815655055: NewerSimpleUnionTag.v,
};


class NewerSimpleUnion extends $fidl.XUnion {

  const NewerSimpleUnion.withI(int value)
    : _ordinal = 693944286, _data = value;

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

  const NewerSimpleUnion.withV(List<String> value)
    : _ordinal = 1815655055, _data = value;

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

  final int _ordinal;
  final _data;

  NewerSimpleUnionTag get tag => _NewerSimpleUnionTag_map[_ordinal];


  int get i {
    if (_ordinal != 693944286) {
      return null;
    }
    return _data;
  }
  String get s {
    if (_ordinal != 473666119) {
      return null;
    }
    return _data;
  }
  List<String> get v {
    if (_ordinal != 1815655055) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 693944286:
        return 'NewerSimpleUnion.i($i)';
      case 473666119:
        return 'NewerSimpleUnion.s($s)';
      case 1815655055:
        return 'NewerSimpleUnion.v($v)';
      default:
        return null;
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<NewerSimpleUnion> kNewerSimpleUnion_Type = const $fidl.XUnionType<NewerSimpleUnion>(
  encodedSize: 24,
  members: const <int, $fidl.FidlType>{
    693944286: const $fidl.Int64Type(),
    473666119: const $fidl.StringType(maybeElementCount: null, nullable: false),
    1815655055: const $fidl.VectorType<List<String>>(element: const $fidl.StringType(maybeElementCount: null, nullable: false), maybeElementCount: null, nullable: false),
  },
  ctor: NewerSimpleUnion._ctor,
);
const $fidl.XUnionType<NewerSimpleUnion> kNewerSimpleUnion_OptType = const $fidl.XUnionType<NewerSimpleUnion>(
encodedSize: 24,
members: const <int, $fidl.FidlType>{
    693944286: const $fidl.Int64Type(),
    473666119: const $fidl.StringType(maybeElementCount: null, nullable: false),
    1815655055: const $fidl.VectorType<List<String>>(element: const $fidl.StringType(maybeElementCount: null, nullable: false), maybeElementCount: null, nullable: false),
  },
ctor: NewerSimpleUnion._ctor,
nullable: true,
);

