// 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: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_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 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._(UnionTag tag, Object data)
      : _tag = tag,
        _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 r'Union.primitive($primitive)';
      case UnionTag.stringNeedsConstructor:
        return r'Union.stringNeedsConstructor($stringNeedsConstructor)';
      case UnionTag.vectorStringAlsoNeedsConstructor:
        return r'Union.vectorStringAlsoNeedsConstructor($vectorStringAlsoNeedsConstructor)';
      default:
        return null;
    }
  }

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

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

  @override
  Object get $data => _data;

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

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