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

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

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,
);

enum FieldCollisionTag {
  fieldCollisionTag,
}

class FieldCollision extends $fidl.Union {
  const FieldCollision.withFieldCollisionTag(int value)
      : _data = value,
        _tag = FieldCollisionTag.fieldCollisionTag;

  FieldCollision._(FieldCollisionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final FieldCollisionTag _tag;
  final _data;
  int get fieldCollisionTag {
    if (_tag != FieldCollisionTag.fieldCollisionTag) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case FieldCollisionTag.fieldCollisionTag:
        return r'FieldCollision.fieldCollisionTag($fieldCollisionTag)';
      default:
        return null;
    }
  }

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

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

  @override
  Object get $data => _data;

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FieldCollision> kFieldCollision_Type =
    $fidl.UnionType<FieldCollision>(
  encodedSize: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offset: 4),
  ],
  ctor: FieldCollision._ctor,
);

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