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

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

import 'package:fidl_zx/fidl_async.dart' as lib$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: directives_ordering
// 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 int answer = 0x2a;

const int answerInBinary = 0x2a;

const double conversionFactor = 1.41421;

const int diamond = 0x183c7effff7e3c18;

const bool enabledFlag = true;

const int fuchsia = 0x3844828282453906;

const double minTemp = -273.15;

const int offset = -33;

const int populationUsa2018 = 0x13ab6680;

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

const int zxConst = lib$zx.channelMaxMsgBytes;

const lib$zx.ObjType zxObjVal = lib$zx.ObjType.channel;

const lib$zx.Rights zxRightsVal = lib$zx.Rights.read;

const int bitsPrimitiveTrue = BitsType.true$;

const int bitsPrimitiveVal = BitsType.value;

const BitsType bitsTrue = BitsType.true$;

const BitsType bitsVal = BitsType.value;

const int enumPrimitiveTrue = EnumType.true$;

const int enumPrimitiveVal = EnumType.value;

const EnumType enumTrue = EnumType.true$;

const EnumType enumVal = EnumType.value;

class EnumType extends $fidl.Enum {
  static const Map<int, EnumType> _values = {
    0x1: value,
    0x2: true$,
  };
  factory EnumType(int _v) {
    if (!_values.containsKey(_v)) {
      throw $fidl.FidlError('Invalid strict enum value: $_v',
          $fidl.FidlErrorCode.fidlInvalidEnumValue);
    }
    return _values[_v]!;
  }
  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;
  }

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

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

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