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

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

// ordinalFive: ()
const int _kSwitchingOrdinals_OrdinalFive_Ordinal = 0x7784636700000000;
const $fidl.MethodType _kSwitchingOrdinals_OrdinalFive_Type = $fidl.MethodType(
  request: null,
  response: null,
  name: r"SwitchingOrdinals.OrdinalFive",
);
// onlyGeneratedOrdinal: ()
const int _kSwitchingOrdinals_OnlyGeneratedOrdinal_Ordinal = 0x27c9581f00000000;
const $fidl.MethodType _kSwitchingOrdinals_OnlyGeneratedOrdinal_Type =
    $fidl.MethodType(
  request: null,
  response: null,
  name: r"SwitchingOrdinals.OnlyGeneratedOrdinal",
);
// eventOrdinalFifteen:  -> ()
const int _kSwitchingOrdinals_EventOrdinalFifteen_Ordinal = 0x577495a100000000;
const $fidl.MethodType _kSwitchingOrdinals_EventOrdinalFifteen_Type =
    $fidl.MethodType(
  request: null,
  response: null,
  name: r"SwitchingOrdinals.EventOrdinalFifteen",
);
// eventOnlyGeneratedOrdinal:  -> ()
const int _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_Ordinal =
    0x7fec464e00000000;
const $fidl.MethodType _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_Type =
    $fidl.MethodType(
  request: null,
  response: null,
  name: r"SwitchingOrdinals.EventOnlyGeneratedOrdinal",
);

abstract class SwitchingOrdinals extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => SwitchingOrdinalsData();
  $async.Future<void> ordinalFive();
  $async.Future<void> onlyGeneratedOrdinal();
  $async.Stream<void> get eventOrdinalFifteen;
  $async.Stream<void> get eventOnlyGeneratedOrdinal;
}

class SwitchingOrdinalsData implements $fidl.ServiceData<SwitchingOrdinals> {
  const SwitchingOrdinalsData();

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

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

class SwitchingOrdinalsProxy extends $fidl.AsyncProxy<SwitchingOrdinals>
    implements SwitchingOrdinals {
  SwitchingOrdinalsProxy()
      : super($fidl.AsyncProxyController<SwitchingOrdinals>(
            $serviceName: null, $interfaceName: r'SwitchingOrdinals')) {
    ctrl.onResponse = _handleResponse;
    ctrl.whenClosed.then((_) {
      _eventOrdinalFifteenEventStreamController.close();
      _eventOnlyGeneratedOrdinalEventStreamController.close();
    }, onError: (_) {});
  }

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      case _kSwitchingOrdinals_EventOrdinalFifteen_Ordinal:
        final String _name = _kSwitchingOrdinals_EventOrdinalFifteen_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kSwitchingOrdinals_EventOrdinalFifteen_Type.response;
          $decoder.claimMemory(16);
          _eventOrdinalFifteenEventStreamController.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;
      case _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_Ordinal:
        final String _name =
            _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_Type.response;
          $decoder.claimMemory(16);
          _eventOnlyGeneratedOrdinalEventStreamController.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;
    }
  }

  @override
  $async.Future<void> ordinalFive() 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(_kSwitchingOrdinals_OrdinalFive_Ordinal, 0);
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  @override
  $async.Future<void> onlyGeneratedOrdinal() 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(
        _kSwitchingOrdinals_OnlyGeneratedOrdinal_Ordinal, 0);
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  final _eventOrdinalFifteenEventStreamController =
      $async.StreamController<void>.broadcast();
  @override
  $async.Stream<void> get eventOrdinalFifteen =>
      _eventOrdinalFifteenEventStreamController.stream;

  final _eventOnlyGeneratedOrdinalEventStreamController =
      $async.StreamController<void>.broadcast();
  @override
  $async.Stream<void> get eventOnlyGeneratedOrdinal =>
      _eventOnlyGeneratedOrdinalEventStreamController.stream;
}

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

    whenBound.then((_) {
      if (impl.eventOrdinalFifteen != null) {
        $subscriptions.add(impl.eventOrdinalFifteen.listen(($response) {
          final $fidl.Encoder $encoder = $fidl.Encoder();
          $encoder.encodeMessageHeader(
              _kSwitchingOrdinals_EventOrdinalFifteen_Ordinal, 0);
          $encoder.alloc(16 - $fidl.kMessageHeaderSize);
          final List<$fidl.MemberType> $types =
              _kSwitchingOrdinals_EventOrdinalFifteen_Type.response;

          sendMessage($encoder.message);
        }));
      }
      if (impl.eventOnlyGeneratedOrdinal != null) {
        $subscriptions.add(impl.eventOnlyGeneratedOrdinal.listen(($response) {
          final $fidl.Encoder $encoder = $fidl.Encoder();
          $encoder.encodeMessageHeader(
              _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_Ordinal, 0);
          $encoder.alloc(16 - $fidl.kMessageHeaderSize);
          final List<$fidl.MemberType> $types =
              _kSwitchingOrdinals_EventOnlyGeneratedOrdinal_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 _kSwitchingOrdinals_OrdinalFive_Ordinal:
        final String _name = _kSwitchingOrdinals_OrdinalFive_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kSwitchingOrdinals_OrdinalFive_Type.request;
          $decoder.claimMemory(16);
          final $async.Future<void> $future = impl.ordinalFive();
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kSwitchingOrdinals_OnlyGeneratedOrdinal_Ordinal:
        final String _name = _kSwitchingOrdinals_OnlyGeneratedOrdinal_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kSwitchingOrdinals_OnlyGeneratedOrdinal_Type.request;
          $decoder.claimMemory(16);
          final $async.Future<void> $future = impl.onlyGeneratedOrdinal();
          // 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 SwitchingOrdinalsBinding');
    }
  }
}
