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

library fidl_fidl_test_consts_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

const bool enabledFlag = true;

const int offset = -33;

const int answer = 0x2a;

const int answerInBinary = 0x2a;

const int populationUsa2018 = 0x13ab6680;

const int diamond = 0x183c7effff7e3c18;

const int fuchsia = 0x3844828282453906;

const String username = "\"squeenze\"";

const double minTemp = -273.15;

const double conversionFactor = 1.41421;

const EnumType enumVal = EnumType.value;

const int enumPrimitiveVal = EnumType.value;

const EnumType enumTrue = EnumType.true$;

const int enumPrimitiveTrue = EnumType.true$;

const BitsType bitsVal = BitsType.value;

const int bitsPrimitiveVal = BitsType.value;

const BitsType bitsTrue = BitsType.true$;

const int bitsPrimitiveTrue = BitsType.true$;

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

  const EnumType._(this.$value);

  @override
  final int $value;

  static const Map<String, EnumType> $valuesMap = {
    r'value': value,
    r'true$': true$,
  };

  static const List<EnumType> $values = [
    value,
    true$,
  ];

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

  @override
  bool isUnknown() {
    return false;
  }

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

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

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

class BitsType extends $fidl.Bits {
  factory BitsType(int _v) {
    if ((_v & ~$mask.$value) != 0) {
      throw $fidl.FidlError('Bits value contains unknown bit(s): $_v',
          $fidl.FidlErrorCode.fidlInvalidBit);
    }
    return BitsType._(_v);
  }
  static const BitsType value = BitsType._(0x1);
  static const BitsType true$ = BitsType._(0x2);
  static const BitsType $none = BitsType._(0);
  static const BitsType $mask = BitsType._(0x3);

  const BitsType._(this.$value);

  BitsType operator |(BitsType other) {
    return BitsType._($value | other.$value);
  }

  BitsType operator &(BitsType other) {
    return BitsType._($value & other.$value);
  }

  BitsType operator ~() {
    return BitsType._(~$value & $mask.$value);
  }

  @override
  final int $value;

  @override
  bool hasUnknownBits() {
    return getUnknownBits() != 0;
  }

  @override
  int getUnknownBits() {
    return $value & ~$mask.$value;
  }

  @override
  String toString() {
    List<String> parts = [];
    if ($value & 0x1 != 0) {
      parts.add(r'BitsType.value');
    }
    if ($value & 0x2 != 0) {
      parts.add(r'BitsType.true$');
    }
    if (parts.isEmpty) {
      return r'BitsType.$none';
    } else {
      return parts.join(" | ");
    }
  }

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

const $fidl.BitsType<BitsType> kBitsType_Type =
    $fidl.BitsType<BitsType>(type: $fidl.Uint32Type(), ctor: BitsType._ctor);

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