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

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

/// flexible enum comment #1.
///
/// flexible enum comment #2.
class MyFlexibleEnum extends $fidl.Enum {
  static final Map<int, MyFlexibleEnum> _values = {
    0x1: foo,
    0x2: bar,
  };
  factory MyFlexibleEnum(int _v) {
    if (!_values.containsKey(_v)) {
      _values[_v] = MyFlexibleEnum._(_v, true);
    }
    return _values[_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;
  }

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

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

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

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

const $fidl.BitsType<MyFlexibleBits> kMyFlexibleBits_Type =
    $fidl.BitsType<MyFlexibleBits>(
        type: $fidl.Uint32Type(), ctor: MyFlexibleBits._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;
  }

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

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

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.Union {
  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
  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,
);

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.Union {
  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
  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,
);

/// 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 $cloneWith({
    int? field,
  }) {
    return Struct(
      field: field ?? this.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, int $depth) {
    $fieldType0.encode($encoder, field, $offset + 0, $depth);
  }

  static Struct _structDecode($fidl.Decoder $decoder, int $offset, int $depth) {
    switch ($decoder.wireFormat) {
      case $fidl.WireFormat.v1:
      case $fidl.WireFormat.v2:
        return Struct(field: $fieldType0.decode($decoder, $offset + 0, $depth));
      default:
        throw $fidl.FidlError('unknown wire format');
    }
  }
}

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

  Table $cloneWith({
    $fidl.OptionalNullable<Map<int, $fidl.UnknownRawData>> $unknownData =
        const $fidl.OptionalNullable.undefined(),
    $fidl.OptionalNullable<int> field =
        const $fidl.OptionalNullable.undefined(),
  }) {
    return Table(
      field: field.or(this.field),
    );
  }

  @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,
);

// method: ()
const int _kInterface_Method_Ordinal = 0x45a0257b7cd8f999;
const $fidl.MethodType _kInterface_Method_Type = $fidl.MethodType(
  request: [],
  response: [],
  name: r"Interface.Method",
  requestInlineSizeV2: 0,
  responseInlineSizeV2: 0,
);
// onEvent:  -> ()
const int _kInterface_OnEvent_Ordinal = 0x663f6d5971bef0;
const $fidl.MethodType _kInterface_OnEvent_Type = $fidl.MethodType(
  request: [],
  response: [],
  name: r"Interface.OnEvent",
  requestInlineSizeV2: 0,
  responseInlineSizeV2: 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.IncomingMessage $message) {
    switch ($message.ordinal) {
      case _kInterface_OnEvent_Ordinal:
        final String _name = _kInterface_OnEvent_Type.name;
        $fidl.performCtrlWithExceptionHandling(
            _name, ctrl, 'event', _onEventEventStreamController.addError, () {
          final List<$fidl.MemberType> $types =
              _kInterface_OnEvent_Type.response!;
          // ignore: prefer_const_declarations
          final $response = null;

          _onEventEventStreamController.add($response);
        });
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        break;
    }
  }

  void _handleResponse($fidl.IncomingMessage $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}'));
        break;
    }
  }

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

    final $fidl.Encoder $encoder = $fidl.Encoder($fidl.kWireFormatDefault);
    $encoder.encodeMessageHeader(
        _kInterface_Method_Ordinal, 0, $fidl.CallStrictness.strict);
    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($fidl.kWireFormatDefault);
            $encoder.encodeMessageHeader(
                _kInterface_OnEvent_Ordinal, 0, $fidl.CallStrictness.strict);
            final List<$fidl.MemberType> $types =
                _kInterface_OnEvent_Type.response!;

            sendMessage($encoder.message);
          },
              // TODO: was ignoring errors intentional here? For methods, the
              // channel gets closed on error.
              onError: (_e) {
            $fidl.handleException(_kInterface_OnEvent_Type.name, _e, close);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kInterface_Method_Ordinal:
        final String _name = _kInterface_Method_Type.name;
        $fidl.performWithExceptionHandling(_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.requestInlineSize(
                      $message.wireFormat), ($fidl.Decoder decoder) {
            return _impl.method();
          });
        }, close);
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for InterfaceBinding');
    }
  }
}
