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

library fidl_fidl_test_bitsconstants_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 BitsType const1 = BitsType.a;

const BitsType const2 = BitsType._(129);

const BitsType const3 = BitsType._(131);

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 a = BitsType._(0x1);
  static const BitsType b = BitsType._(0x80);
  static const BitsType c = BitsType._(0x2);
  static const BitsType $none = BitsType._(0);
  static const BitsType $mask = BitsType._(0x83);

  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.a');
    }
    if ($value & 0x80 != 0) {
      parts.add(r'BitsType.b');
    }
    if ($value & 0x2 != 0) {
      parts.add(r'BitsType.c');
    }
    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();
