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

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

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

// 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.IncomingMessage $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.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}'));
        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.IncomingMessage $message, $fidl.OutgoingMessageSink $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');
    }
  }
}
