// WARNING: This file is machine generated by fidlgen.

library fidl_test_name_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 $zx;

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

/// const comment #1
///
/// const comment #3
const int c = 0x4;

enum UnionTag {
  field,
}

/// union comment #1
///
/// union comment #3
class Union extends $fidl.Union {
  const Union.withField(int value)
      : _data = value,
        _tag = UnionTag.field;

  Union._(UnionTag tag, Object data)
      : _tag = tag,
        _data = data;

  final UnionTag _tag;
  final _data;
  int get field {
    if (_tag != UnionTag.field) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case UnionTag.field:
        return r'Union.field($field)';
      default:
        return null;
    }
  }

  /// union comment #1
  ///
  /// union comment #3

  UnionTag get $tag => _tag;
  // TODO: remove, see: FIDL-587
  UnionTag get tag => _tag;

  @override
  int get $index => _tag.index;

  @override
  Object get $data => _data;

  static Union _ctor(int index, Object data) {
    return Union._(UnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<Union> kUnion_Type = $fidl.UnionType<Union>(
  encodedSize: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offset: 4),
  ],
  ctor: Union._ctor,
);

/// 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._(List<Object> argv) : field = argv[0];

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

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

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

  static Struct _ctor(List<Object> argv) => Struct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Struct> kStruct_Type = $fidl.StructType<Struct>(
  encodedSize: 4,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int32Type(), offset: 0),
  ],
  ctor: Struct._ctor,
);

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

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

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

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

  static Table _ctor(Map<int, dynamic> argv) => Table._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<Table> kTable_Type = $fidl.TableType<Table>(
  encodedSize: 16,
  members: <int, $fidl.FidlType>{
    1: $fidl.Int32Type(),
  },
  ctor: Table._ctor,
);

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

// method: ()
const int _kInterface_Method_Ordinal = 0x3f43684c00000000;
const $fidl.MethodType _kInterface_Method_Type = $fidl.MethodType(
  request: null,
  response: null,
  name: r"Interface.Method",
);
// onEvent:  -> ()
const int _kInterface_OnEvent_Ordinal = 0x136d200d00000000;
const $fidl.MethodType _kInterface_OnEvent_Type = $fidl.MethodType(
  request: null,
  response: null,
  name: r"Interface.OnEvent",
);

/// interface comment #1
///
/// interface comment #3
abstract class Interface extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $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;
}

class InterfaceData implements $fidl.ServiceData<Interface> {
  const InterfaceData();

  @override
  String getName() {
    return Interface.$serviceName;
  }

  @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>(
            $serviceName: null, $interfaceName: r'Interface')) {
    ctrl.onResponse = _handleResponse;
    ctrl.whenClosed.then((_) {
      _onEventEventStreamController.close();
    }, onError: (_) {});
  }

  @override
  $fidl.ServiceData get $serviceData => InterfaceData();

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($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;
          $decoder.claimMemory(16);
          _onEventEventStreamController.add(null);
          // ignore: avoid_catches_without_on_clauses
        } 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);
    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((_) {
      if (impl.onEvent != null) {
        $subscriptions.add(impl.onEvent.listen(($response) {
          final $fidl.Encoder $encoder = $fidl.Encoder();
          $encoder.encodeMessageHeader(_kInterface_OnEvent_Ordinal, 0);
          $encoder.alloc(16 - $fidl.kMessageHeaderSize);
          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);
    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(16);
          final $async.Future<void> $future = impl.method();
          // ignore: avoid_catches_without_on_clauses
        } 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');
    }
  }
}
