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

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 = value;

const BitsType bitsVal = BitsType.value;

const int bitsPrimitiveVal = value;

class EnumType extends $fidl.Enum {
  factory EnumType(int _v) {
    switch (_v) {
      case 0x1:
        return value;
      default:
        return null;
    }
  }
  static const EnumType value = EnumType._(0x1);

  const EnumType._(this.$value);

  @override
  final int $value;

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

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

  // TODO: remove, see: FIDL-587
  static const List<EnumType> values = EnumType.$values;

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

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

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

const $fidl.EnumType<EnumType> kEnumType_Type =
    $fidl.EnumType<EnumType>(type: $fidl.Int32Type(), ctor: EnumType._ctor);

class BitsType extends $fidl.Enum {
  factory BitsType(int _v) {
    switch (_v) {
      case 0x1:
        return value;
      default:
        return null;
    }
  }
  static const BitsType value = BitsType._(0x1);

  const BitsType._(this.$value);

  @override
  final int $value;

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

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

  // TODO: remove, see: FIDL-587
  static const List<BitsType> values = BitsType.$values;

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

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

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

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

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