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

library fidl_fidl_test_doccomments_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 comment #1
///
/// const comment #3
const int c = 0x4;

/// strict enum comment #1.
///
/// strict enum comment #2.
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);
    }
  }

  /// FOO member comment #1
  ///
  /// FOO member comment #3
  static const MyStrictEnum foo = MyStrictEnum._(0x1);

  /// BAR member comment #1
  ///
  /// BAR member comment #3
  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);

/// flexible enum comment #1.
///
/// flexible enum comment #2.
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]!;
  }

  /// FOO member comment #1
  ///
  /// FOO member comment #3
  static const MyFlexibleEnum foo = MyFlexibleEnum._(0x1, false);

  /// BAR member comment #1
  ///
  /// BAR member comment #3
  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);

/// strict bits comment #1
///
/// strict bits comment #2
class MyStrictBits extends $fidl.Bits {
  factory MyStrictBits(int _v) {
    if ((_v & ~$mask.$value) != 0) {
      throw $fidl.FidlError('Bits value contains unknown bit(s): $_v',
          $fidl.FidlErrorCode.fidlInvalidBit);
    }
    return MyStrictBits._(_v);
  }

  /// MY_FIRST_BIT member comment #1
  ///
  /// MY_FIRST_BIT member comment #3
  static const MyStrictBits myFirstBit = MyStrictBits._(0x1);

  /// MY_OTHER_BIT member comment #1
  ///
  /// MY_OTHER_BIT member comment #3
  static const MyStrictBits myOtherBit = MyStrictBits._(0x2);
  static const MyStrictBits $none = MyStrictBits._(0);
  static const MyStrictBits $mask = MyStrictBits._(0x3);

  const MyStrictBits._(this.$value);

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

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

  MyStrictBits operator ~() {
    return MyStrictBits._(~$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'MyStrictBits.myFirstBit');
    }
    if ($value & 0x2 != 0) {
      parts.add(r'MyStrictBits.myOtherBit');
    }
    if (parts.isEmpty) {
      return r'MyStrictBits.$none';
    } else {
      return parts.join(" | ");
    }
  }

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

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

/// flexible bits comment #1
///
/// flexible bits comment #2
class MyFlexibleBits extends $fidl.Bits {
  factory MyFlexibleBits(int _v) {
    return MyFlexibleBits._(_v);
  }

  /// MY_FIRST_BIT member comment #1
  ///
  /// MY_FIRST_BIT member comment #3
  static const MyFlexibleBits myFirstBit = MyFlexibleBits._(0x1);

  /// MY_OTHER_BIT member comment #1
  ///
  /// MY_OTHER_BIT member comment #3
  static const MyFlexibleBits myOtherBit = MyFlexibleBits._(0x2);
  static const MyFlexibleBits $none = MyFlexibleBits._(0);
  static const MyFlexibleBits $mask = MyFlexibleBits._(0x3);

  const MyFlexibleBits._(this.$value);

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

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

  MyFlexibleBits operator ~() {
    return MyFlexibleBits._(~$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'MyFlexibleBits.myFirstBit');
    }
    if ($value & 0x2 != 0) {
      parts.add(r'MyFlexibleBits.myOtherBit');
    }
    if (hasUnknownBits()) {
      parts.add('0x${getUnknownBits().toRadixString(16)}');
    }
    if (parts.isEmpty) {
      return r'MyFlexibleBits.$none';
    } else {
      return parts.join(" | ");
    }
  }

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

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

enum StrictUnionTag {
  field, // 0x1
}

const Map<int, StrictUnionTag> _StrictUnionTag_map = {
  1: StrictUnionTag.field,
};

/// strict union comment #1
///
/// strict union comment #3
class StrictUnion extends $fidl.XUnion {
  const StrictUnion.withField(int value)
      : _ordinal = 1,
        _data = value;

  StrictUnion._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  StrictUnionTag get $tag => _StrictUnionTag_map[_ordinal]!;

  int? get field {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'StrictUnion.field(' + field.toString() + ')';
      default:
        return r'StrictUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static StrictUnion _ctor(int ordinal, Object data) {
    return StrictUnion._(ordinal, data);
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictUnion> kStrictUnion_Type =
    $fidl.UnionType<StrictUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: StrictUnion._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictUnion> kStrictUnion_OptType =
    $fidl.NullableUnionType<StrictUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: StrictUnion._ctor,
  flexible: false,
  resource: false,
);

enum FlexibleUnionTag {
  $unknown,
  field, // 0x1
}

const Map<int, FlexibleUnionTag> _FlexibleUnionTag_map = {
  1: FlexibleUnionTag.field,
};

/// flexible union comment #1
///
/// flexible union comment #3
class FlexibleUnion extends $fidl.XUnion {
  const FlexibleUnion.withField(int value)
      : _ordinal = 1,
        _data = value;
  const FlexibleUnion.with$UnknownData(this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

  FlexibleUnion._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  FlexibleUnionTag get $tag =>
      _FlexibleUnionTag_map[_ordinal] ?? FlexibleUnionTag.$unknown;

  int? get field {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'FlexibleUnion.field(' + field.toString() + ')';
      default:
        return r'FlexibleUnion.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static FlexibleUnion _ctor(int ordinal, Object data) {
    return FlexibleUnion._(ordinal, data);
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FlexibleUnion> kFlexibleUnion_Type =
    $fidl.UnionType<FlexibleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: FlexibleUnion._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<FlexibleUnion> kFlexibleUnion_OptType =
    $fidl.NullableUnionType<FlexibleUnion>(
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: FlexibleUnion._ctor,
  flexible: true,
  resource: false,
);

/// struct comment #1
///
/// struct comment #3
class Struct extends $fidl.Struct {
  const Struct({
    required this.field,
  });
  Struct.clone(
    Struct $orig, {
    int? field,
  }) : this(
          field: field ?? $orig.field,
        );

  /// struct member comment #1
  ///
  /// struct member comment #3
  final int field;

  @override
  List<Object?> get $fields {
    return <Object?>[
      field,
    ];
  }

  static const $fieldType0 = $fidl.Int32Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, field, $offset + 0);
  }

  @override
  String toString() {
    return r'Struct' r'(field: ' + field.toString() + r')';
  }

  static Struct _structDecode($fidl.Decoder $decoder, int $offset) {
    return Struct(field: $fieldType0.decode($decoder, $offset + 0));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Struct> kStruct_Type = $fidl.StructType<Struct>(
  inlineSize: 4,
  structDecode: Struct._structDecode,
);

/// table comment #1
///
/// table comment #3
class Table extends $fidl.Table {
  const Table({
    this.$unknownData,
    this.field,
  });

  Table._(Map<int, dynamic> argv, this.$unknownData) : field = argv[1];

  @override
  final Map<int, $fidl.UnknownRawData>? $unknownData;

  /// table field comment #1
  ///
  /// table field comment #3
  final int? field;

  @override
  dynamic $field(int index) {
    switch (index) {
      case 0:
        return field;
    }
    return null;
  }

  @override
  Map<int, dynamic> get $fields {
    return {
      1: field,
    };
  }

  static Table _ctor(Map<int, dynamic> argv,
          [Map<int, $fidl.UnknownRawData>? unknownData]) =>
      Table._(argv, unknownData);
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.TableType<Table> kTable_Type = $fidl.TableType<Table>(
  inlineSize: 16,
  members: [
    $fidl.Int32Type(),
  ],
  ctor: Table._ctor,
  resource: false,
);

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

// method: ()
const int _kInterface_Method_Ordinal = 0x5c492542705b4265;
const $fidl.MethodType _kInterface_Method_Type = $fidl.MethodType(
  request: [],
  response: [],
  name: r"Interface.Method",
  requestInlineSize: 0,
  responseInlineSize: 0,
);
// onEvent:  -> ()
const int _kInterface_OnEvent_Ordinal = 0x37812b697096f6fa;
const $fidl.MethodType _kInterface_OnEvent_Type = $fidl.MethodType(
  request: [],
  response: [],
  name: r"Interface.OnEvent",
  requestInlineSize: 0,
  responseInlineSize: 0,
);

/// interface comment #1
///
/// interface comment #3
abstract class Interface {
  $fidl.ServiceData? get $serviceData => InterfaceData();

  /// method comment #1
  ///
  /// method comment #3
  $async.Future<void> method();

  /// event comment #1
  ///
  /// event comment #3
  $async.Stream<void>? get onEvent;
}

// TODO: Remove ServiceData for non-service
class InterfaceData implements $fidl.ServiceData<Interface> {
  const InterfaceData();

  @override
  String getName() {
    return "";
  }

  @override
  $fidl.AsyncBinding getBinding() {
    return InterfaceBinding();
  }
}

/// interface comment #1
///
/// interface comment #3
class InterfaceProxy extends $fidl.AsyncProxy<Interface> implements Interface {
  InterfaceProxy()
      : super($fidl.AsyncProxyController<Interface>(
            $interfaceName: r'Interface')) {
    ctrl.onResponse = _handleResponse;
    ctrl.whenClosed.then((_) {
      _onEventEventStreamController.close();
    }, onError: (_) {});
  }
  @override
  Null get $serviceData => null;

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    switch ($message.ordinal) {
      case _kInterface_OnEvent_Ordinal:
        final String _name = _kInterface_OnEvent_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kInterface_OnEvent_Type.response!;
          $decoder.claimMemory(
              _kInterface_OnEvent_Type.decodeResponseInlineSize($decoder));
          _onEventEventStreamController.add(null);
        } catch (_e) {
          ctrl.proxyError(
              $fidl.FidlError('Exception handling event $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.Message $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  /// method comment #1
  ///
  /// method comment #3
  @override
  $async.Future<void> method() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kInterface_Method_Ordinal, 0);
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  final _onEventEventStreamController =
      $async.StreamController<void>.broadcast();

  /// event comment #1
  ///
  /// event comment #3
  @override
  $async.Stream<void> get onEvent => _onEventEventStreamController.stream;
}

class InterfaceBinding extends $fidl.AsyncBinding<Interface> {
  InterfaceBinding() : super(r"Interface") {
    final List<$async.StreamSubscription<dynamic>> $subscriptions = [];
    void $unsubscribe() {
      for (final $sub in $subscriptions) {
        $sub.cancel();
      }
      $subscriptions.clear();
    }

    whenBound.then((_) {
      final impl = this.impl;
      if (impl != null) {
        final _onEvent_stream = impl.onEvent;
        if (_onEvent_stream != null) {
          $subscriptions.add(_onEvent_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kInterface_OnEvent_Ordinal, 0);
            $encoder.alloc(
                _kInterface_OnEvent_Type.encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kInterface_OnEvent_Type.response!;

            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    switch ($message.ordinal) {
      case _kInterface_Method_Ordinal:
        final String _name = _kInterface_Method_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kInterface_Method_Type.request!;
          $decoder.claimMemory(
              _kInterface_Method_Type.decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = impl!.method();
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for InterfaceBinding');
    }
  }
}
