// 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';
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.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 UnionTag {
  primitive,
  stringNeedsConstructor,
  vectorStringAlsoNeedsConstructor,
}
class Union extends $fidl.Union {

  const Union.withPrimitive(int value)
    : _data = value, tag = UnionTag.primitive;

  const Union.withStringNeedsConstructor(String value)
    : _data = value, tag = UnionTag.stringNeedsConstructor;

  const Union.withVectorStringAlsoNeedsConstructor(List<String> value)
    : _data = value, tag = UnionTag.vectorStringAlsoNeedsConstructor;

  Union._(this.tag, Object data) : _data = data;

  final UnionTag tag;
  final _data;
  int get primitive {
    if (tag != UnionTag.primitive) {
      return null;
    }
    return _data;
  }
  String get stringNeedsConstructor {
    if (tag != UnionTag.stringNeedsConstructor) {
      return null;
    }
    return _data;
  }
  List<String> get vectorStringAlsoNeedsConstructor {
    if (tag != UnionTag.vectorStringAlsoNeedsConstructor) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (tag) {
      case UnionTag.primitive:
        return 'Union.primitive($primitive)';
      case UnionTag.stringNeedsConstructor:
        return 'Union.stringNeedsConstructor($stringNeedsConstructor)';
      case UnionTag.vectorStringAlsoNeedsConstructor:
        return 'Union.vectorStringAlsoNeedsConstructor($vectorStringAlsoNeedsConstructor)';
      default:
        return null;
    }
  }
  @override
  int get $index => tag.index;

  @override
  Object get $data => _data;

  static Union _ctor(int index, Object data) {
    return new Union._(UnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<Union> kUnion_Type = const $fidl.UnionType<Union>(
  encodedSize: 24,
  members: const <$fidl.MemberType>[
    const $fidl.MemberType<int>(type: const $fidl.Int32Type(), offset: 8),
    const $fidl.MemberType<String>(type: const $fidl.StringType(maybeElementCount: null, nullable: false), offset: 8),
    const $fidl.MemberType<List<String>>(type: const $fidl.VectorType<List<String>>(element: const $fidl.StringType(maybeElementCount: null, nullable: false), maybeElementCount: null, nullable: false), offset: 8),
  ],
  ctor: Union._ctor,
);

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

