// 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) {
    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!;
          _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;
    }
    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);
            final List<$fidl.MemberType> $types =
                _kInterface_OnEvent_Type.response!;

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

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message, _kInterface_Method_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _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');
    }
  }
}
