// WARNING: This file is machine generated by fidlgen_dart.
// @dart = 2.12

library fidl_fidl_test_enum_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 $zircon;

// 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
// ignore_for_file: prefer_interpolation_to_compose_strings

class MyStrictEnum extends $fidl.Enum {
  factory MyStrictEnum(int _v) {
    switch (_v) {
      case 0x1:
        return foo;
      case 0x2:
        return bar;
      default:
        throw $fidl.FidlError('Invalid strict enum value: $_v',
            $fidl.FidlErrorCode.fidlInvalidEnumValue);
    }
  }
  static const MyStrictEnum foo = MyStrictEnum._(0x1);
  static const MyStrictEnum bar = MyStrictEnum._(0x2);

  const MyStrictEnum._(this.$value);

  @override
  final int $value;

  static const Map<String, MyStrictEnum> $valuesMap = {
    r'foo': foo,
    r'bar': bar,
  };

  static const List<MyStrictEnum> $values = [
    foo,
    bar,
  ];

  static MyStrictEnum? $valueOf(String name) => $valuesMap[name];

  @override
  bool isUnknown() {
    return false;
  }

  @override
  String toString() {
    switch ($value) {
      case 0x1:
        return r'MyStrictEnum.foo';
      case 0x2:
        return r'MyStrictEnum.bar';
      default:
        return r'MyStrictEnum.' '${$value}';
    }
  }

  static MyStrictEnum _ctor(int v) => MyStrictEnum(v);
}

const $fidl.EnumType<MyStrictEnum> kMyStrictEnum_Type =
    $fidl.EnumType<MyStrictEnum>(
        type: $fidl.Uint32Type(),
        values: {0x1: null, 0x2: null},
        ctor: MyStrictEnum._ctor);

class MyFlexibleEnum extends $fidl.Enum {
  static final Map<int, MyFlexibleEnum> _internedValues = {
    0x1: foo,
    0x2: bar,
  };
  factory MyFlexibleEnum(int _v) {
    if (!_internedValues.containsKey(_v)) {
      _internedValues[_v] = MyFlexibleEnum._(_v, true);
    }
    return _internedValues[_v]!;
  }
  static const MyFlexibleEnum foo = MyFlexibleEnum._(0x1, false);
  static const MyFlexibleEnum bar = MyFlexibleEnum._(0x2, false);

  /// Default unknown placeholder.
  static const MyFlexibleEnum $unknown = MyFlexibleEnum._(0xffffffff, true);

  const MyFlexibleEnum._(this.$value, this._isUnknown);

  @override
  final int $value;

  final bool _isUnknown;

  static const Map<String, MyFlexibleEnum> $valuesMap = {
    r'foo': foo,
    r'bar': bar,
  };

  static const List<MyFlexibleEnum> $values = [
    foo,
    bar,
  ];

  static MyFlexibleEnum? $valueOf(String name) => $valuesMap[name];

  @override
  bool isUnknown() {
    return _isUnknown;
  }

  @override
  String toString() {
    switch ($value) {
      case 0x1:
        return r'MyFlexibleEnum.foo';
      case 0x2:
        return r'MyFlexibleEnum.bar';
      default:
        return r'MyFlexibleEnum.' '${$value}';
    }
  }

  static MyFlexibleEnum _ctor(int v) => MyFlexibleEnum(v);
}

const $fidl.EnumType<MyFlexibleEnum> kMyFlexibleEnum_Type =
    $fidl.EnumType<MyFlexibleEnum>(
        type: $fidl.Uint32Type(),
        values: {0x1: null, 0x2: null},
        ctor: MyFlexibleEnum._ctor);

class MyFlexibleEnumWithCustomUnknown extends $fidl.Enum {
  static final Map<int, MyFlexibleEnumWithCustomUnknown> _internedValues = {
    0x1: foo,
    0x2: bar,
    0x3: customUnknown,
  };
  factory MyFlexibleEnumWithCustomUnknown(int _v) {
    if (!_internedValues.containsKey(_v)) {
      _internedValues[_v] = MyFlexibleEnumWithCustomUnknown._(_v, true);
    }
    return _internedValues[_v]!;
  }
  static const MyFlexibleEnumWithCustomUnknown foo =
      MyFlexibleEnumWithCustomUnknown._(0x1, false);
  static const MyFlexibleEnumWithCustomUnknown bar =
      MyFlexibleEnumWithCustomUnknown._(0x2, false);
  static const MyFlexibleEnumWithCustomUnknown customUnknown =
      MyFlexibleEnumWithCustomUnknown._(0x3, true);

  /// Default unknown placeholder.
  static const MyFlexibleEnumWithCustomUnknown $unknown =
      MyFlexibleEnumWithCustomUnknown._(0x3, true);

  const MyFlexibleEnumWithCustomUnknown._(this.$value, this._isUnknown);

  @override
  final int $value;

  final bool _isUnknown;

  static const Map<String, MyFlexibleEnumWithCustomUnknown> $valuesMap = {
    r'foo': foo,
    r'bar': bar,
    r'customUnknown': customUnknown,
  };

  static const List<MyFlexibleEnumWithCustomUnknown> $values = [
    foo,
    bar,
    customUnknown,
  ];

  static MyFlexibleEnumWithCustomUnknown? $valueOf(String name) =>
      $valuesMap[name];

  @override
  bool isUnknown() {
    return _isUnknown;
  }

  @override
  String toString() {
    switch ($value) {
      case 0x1:
        return r'MyFlexibleEnumWithCustomUnknown.foo';
      case 0x2:
        return r'MyFlexibleEnumWithCustomUnknown.bar';
      case 0x3:
        return r'MyFlexibleEnumWithCustomUnknown.customUnknown';
      default:
        return r'MyFlexibleEnumWithCustomUnknown.' '${$value}';
    }
  }

  static MyFlexibleEnumWithCustomUnknown _ctor(int v) =>
      MyFlexibleEnumWithCustomUnknown(v);
}

const $fidl.EnumType<MyFlexibleEnumWithCustomUnknown>
    kMyFlexibleEnumWithCustomUnknown_Type =
    $fidl.EnumType<MyFlexibleEnumWithCustomUnknown>(
        type: $fidl.Uint32Type(),
        values: {0x1: null, 0x2: null, 0x3: null},
        ctor: MyFlexibleEnumWithCustomUnknown._ctor);

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