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

// 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.dart' as $strongly_connect_sync;

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

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

const Map<int, OlderSimpleUnionTag> _OlderSimpleUnionTag_map = {
  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 OlderSimpleUnion._(ordinal, data);
  }
}

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

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

const Map<int, NewerSimpleUnionTag> _NewerSimpleUnionTag_map = {
  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 NewerSimpleUnion._(ordinal, data);
  }
}

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

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