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

class ErrorEnun extends $fidl.Enum {
  factory ErrorEnun(int _v) {
    switch (_v) {
      case 0x1:
        return errFoo;
      case 0x2:
        return errBar;
      default:
        return null;
    }
  }
  static const ErrorEnun errFoo = ErrorEnun._(0x1);
  static const ErrorEnun errBar = ErrorEnun._(0x2);

  const ErrorEnun._(this.$value);

  @override
  final int $value;

  static const Map<String, ErrorEnun> $valuesMap = {
    r'errFoo': errFoo,
    r'errBar': errBar,
  };

  static const List<ErrorEnun> $values = [
    errFoo,
    errBar,
  ];

  // TODO: remove, see: FIDL-587
  static const List<ErrorEnun> values = ErrorEnun.$values;

  static ErrorEnun $valueOf(String name) => $valuesMap[name];

  @override
  String toString() {
    switch ($value) {
      case 0x1:
        return r'ErrorEnun.errFoo';
      case 0x2:
        return r'ErrorEnun.errBar';
      default:
        return null;
    }
  }

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

const $fidl.EnumType<ErrorEnun> kErrorEnun_Type =
    $fidl.EnumType<ErrorEnun>(type: $fidl.Uint32Type(), ctor: ErrorEnun._ctor);

enum WithErrorSyntaxErrorAsPrimitiveResultTag {
  response,
  err,
}

class WithErrorSyntaxErrorAsPrimitiveResult extends $fidl.Union {
  const WithErrorSyntaxErrorAsPrimitiveResult.withResponse(
      WithErrorSyntaxErrorAsPrimitiveResponse value)
      : _data = value,
        _tag = WithErrorSyntaxErrorAsPrimitiveResultTag.response;

  const WithErrorSyntaxErrorAsPrimitiveResult.withErr(int value)
      : _data = value,
        _tag = WithErrorSyntaxErrorAsPrimitiveResultTag.err;

  WithErrorSyntaxErrorAsPrimitiveResult._(
      WithErrorSyntaxErrorAsPrimitiveResultTag tag, Object data)
      : _tag = tag,
        _data = data;

  final WithErrorSyntaxErrorAsPrimitiveResultTag _tag;
  final _data;
  WithErrorSyntaxErrorAsPrimitiveResponse get response {
    if (_tag != WithErrorSyntaxErrorAsPrimitiveResultTag.response) {
      return null;
    }
    return _data;
  }

  int get err {
    if (_tag != WithErrorSyntaxErrorAsPrimitiveResultTag.err) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case WithErrorSyntaxErrorAsPrimitiveResultTag.response:
        return r'WithErrorSyntaxErrorAsPrimitiveResult.response($response)';
      case WithErrorSyntaxErrorAsPrimitiveResultTag.err:
        return r'WithErrorSyntaxErrorAsPrimitiveResult.err($err)';
      default:
        return null;
    }
  }

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

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

  @override
  Object get $data => _data;

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

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

enum WithErrorSyntaxErrorAsEnumResultTag {
  response,
  err,
}

class WithErrorSyntaxErrorAsEnumResult extends $fidl.Union {
  const WithErrorSyntaxErrorAsEnumResult.withResponse(
      WithErrorSyntaxErrorAsEnumResponse value)
      : _data = value,
        _tag = WithErrorSyntaxErrorAsEnumResultTag.response;

  const WithErrorSyntaxErrorAsEnumResult.withErr(ErrorEnun value)
      : _data = value,
        _tag = WithErrorSyntaxErrorAsEnumResultTag.err;

  WithErrorSyntaxErrorAsEnumResult._(
      WithErrorSyntaxErrorAsEnumResultTag tag, Object data)
      : _tag = tag,
        _data = data;

  final WithErrorSyntaxErrorAsEnumResultTag _tag;
  final _data;
  WithErrorSyntaxErrorAsEnumResponse get response {
    if (_tag != WithErrorSyntaxErrorAsEnumResultTag.response) {
      return null;
    }
    return _data;
  }

  ErrorEnun get err {
    if (_tag != WithErrorSyntaxErrorAsEnumResultTag.err) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (_tag) {
      case WithErrorSyntaxErrorAsEnumResultTag.response:
        return r'WithErrorSyntaxErrorAsEnumResult.response($response)';
      case WithErrorSyntaxErrorAsEnumResultTag.err:
        return r'WithErrorSyntaxErrorAsEnumResult.err($err)';
      default:
        return null;
    }
  }

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

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

  @override
  Object get $data => _data;

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<WithErrorSyntaxErrorAsEnumResult>
    kWithErrorSyntax_ErrorAsEnum_Result_Type =
    $fidl.UnionType<WithErrorSyntaxErrorAsEnumResult>(
  encodedSize: 8,
  members: <$fidl.MemberType>[
    $fidl.MemberType<WithErrorSyntaxErrorAsEnumResponse>(
        type: kWithErrorSyntax_ErrorAsEnum_Response_Type, offset: 4),
    $fidl.MemberType<ErrorEnun>(type: kErrorEnun_Type, offset: 4),
  ],
  ctor: WithErrorSyntaxErrorAsEnumResult._ctor,
);

class WithErrorSyntaxErrorAsPrimitiveResponse extends $fidl.Struct {
  const WithErrorSyntaxErrorAsPrimitiveResponse({
    this.reserved: 0x0,
  });
  WithErrorSyntaxErrorAsPrimitiveResponse.clone(
    WithErrorSyntaxErrorAsPrimitiveResponse $orig, {
    int reserved,
  }) : this(
          reserved: reserved ?? $orig.reserved,
        );

  WithErrorSyntaxErrorAsPrimitiveResponse._(List<Object> argv)
      : reserved = argv[0];
  final int reserved;

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

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

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<WithErrorSyntaxErrorAsPrimitiveResponse>
    kWithErrorSyntax_ErrorAsPrimitive_Response_Type =
    $fidl.StructType<WithErrorSyntaxErrorAsPrimitiveResponse>(
  encodedSize: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offset: 0),
  ],
  ctor: WithErrorSyntaxErrorAsPrimitiveResponse._ctor,
);

class WithErrorSyntaxErrorAsEnumResponse extends $fidl.Struct {
  const WithErrorSyntaxErrorAsEnumResponse({
    this.reserved: 0x0,
  });
  WithErrorSyntaxErrorAsEnumResponse.clone(
    WithErrorSyntaxErrorAsEnumResponse $orig, {
    int reserved,
  }) : this(
          reserved: reserved ?? $orig.reserved,
        );

  WithErrorSyntaxErrorAsEnumResponse._(List<Object> argv) : reserved = argv[0];
  final int reserved;

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

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

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

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<WithErrorSyntaxErrorAsEnumResponse>
    kWithErrorSyntax_ErrorAsEnum_Response_Type =
    $fidl.StructType<WithErrorSyntaxErrorAsEnumResponse>(
  encodedSize: 1,
  members: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Uint8Type(), offset: 0),
  ],
  ctor: WithErrorSyntaxErrorAsEnumResponse._ctor,
);

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

// noRequestNoResponse: ()
const int _kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal =
    0x1e03f87500000000;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type = $fidl.MethodType(
  request: null,
  response: null,
  name: r"WithAndWithoutRequestResponse.NoRequestNoResponse",
);
// noRequestEmptyResponse: () -> ()
const int _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal =
    0x4df6dbd500000000;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type =
    $fidl.MethodType(
  request: null,
  response: null,
  name: r"WithAndWithoutRequestResponse.NoRequestEmptyResponse",
);
// noRequestWithResponse: () -> (String ret)
const int _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal =
    0x668d7f800000000;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type =
    $fidl.MethodType(
  request: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 16),
  ],
  name: r"WithAndWithoutRequestResponse.NoRequestWithResponse",
);
// withRequestNoResponse: (String arg)
const int _kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal =
    0x19c2137100000000;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 16),
  ],
  response: null,
  name: r"WithAndWithoutRequestResponse.WithRequestNoResponse",
);
// withRequestEmptyResponse: (String arg) -> ()
const int _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal =
    0x76f2397300000000;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 16),
  ],
  response: null,
  name: r"WithAndWithoutRequestResponse.WithRequestEmptyResponse",
);
// withRequestWithResponse: (String arg) -> (String ret)
const int _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal =
    0x1973292000000000;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 16),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 16),
  ],
  name: r"WithAndWithoutRequestResponse.WithRequestWithResponse",
);
// onEmptyResponse:  -> ()
const int _kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal =
    0x697fd73200000000;
const $fidl.MethodType _kWithAndWithoutRequestResponse_OnEmptyResponse_Type =
    $fidl.MethodType(
  request: null,
  response: null,
  name: r"WithAndWithoutRequestResponse.OnEmptyResponse",
);
// onWithResponse:  -> (String ret)
const int _kWithAndWithoutRequestResponse_OnWithResponse_Ordinal =
    0x7a47120700000000;
const $fidl.MethodType _kWithAndWithoutRequestResponse_OnWithResponse_Type =
    $fidl.MethodType(
  request: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 16),
  ],
  name: r"WithAndWithoutRequestResponse.OnWithResponse",
);

abstract class WithAndWithoutRequestResponse extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => WithAndWithoutRequestResponseData();
  $async.Future<void> noRequestNoResponse();
  $async.Future<void> noRequestEmptyResponse();
  $async.Future<String> noRequestWithResponse();
  $async.Future<void> withRequestNoResponse(String arg);
  $async.Future<void> withRequestEmptyResponse(String arg);
  $async.Future<String> withRequestWithResponse(String arg);
  $async.Stream<void> get onEmptyResponse;
  $async.Stream<String> get onWithResponse;
}

class WithAndWithoutRequestResponseData
    implements $fidl.ServiceData<WithAndWithoutRequestResponse> {
  const WithAndWithoutRequestResponseData();

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

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

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

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      case _kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_OnEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_OnEmptyResponse_Type.response;
          $decoder.claimMemory(16);
          _onEmptyResponseEventStreamController.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 _kWithAndWithoutRequestResponse_OnWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_OnWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_OnWithResponse_Type.response;
          $decoder.claimMemory(32);
          _onWithResponseEventStreamController
              .add($types[0].decode($decoder, 0));
          // 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) {
      case _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                  .response;
          $decoder.claimMemory(16);
          // ignore: prefer_const_declarations
          final $response = null;

          $completer.complete($response);

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                  .response;
          $decoder.claimMemory(32);
          // ignore: prefer_const_declarations
          final $response = $types[0].decode($decoder, 0);

          $completer.complete($response);

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                  .response;
          $decoder.claimMemory(16);
          // ignore: prefer_const_declarations
          final $response = null;

          $completer.complete($response);

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                  .response;
          $decoder.claimMemory(32);
          // ignore: prefer_const_declarations
          final $response = $types[0].decode($decoder, 0);

          $completer.complete($response);

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

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

  @override
  $async.Future<void> noRequestEmptyResponse() 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(
        _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<String> noRequestWithResponse() 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(
        _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal, 0);
    final $completer = $async.Completer<String>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> withRequestNoResponse(String arg) 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(
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal, 0);
    $encoder.alloc(32 - $fidl.kMessageHeaderSize);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type.request;
    $types[0].encode($encoder, arg, 0);
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  @override
  $async.Future<void> withRequestEmptyResponse(String arg) 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(
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal, 0);
    $encoder.alloc(32 - $fidl.kMessageHeaderSize);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.request;
    $types[0].encode($encoder, arg, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<String> withRequestWithResponse(String arg) 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(
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal, 0);
    $encoder.alloc(32 - $fidl.kMessageHeaderSize);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.request;
    $types[0].encode($encoder, arg, 0);
    final $completer = $async.Completer<String>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

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

  final _onWithResponseEventStreamController =
      $async.StreamController<String>.broadcast();
  @override
  $async.Stream<String> get onWithResponse =>
      _onWithResponseEventStreamController.stream;
}

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

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

          sendMessage($encoder.message);
        }));
      }
      if (impl.onWithResponse != null) {
        $subscriptions.add(impl.onWithResponse.listen(($response) {
          final $fidl.Encoder $encoder = $fidl.Encoder();
          $encoder.encodeMessageHeader(
              _kWithAndWithoutRequestResponse_OnWithResponse_Ordinal, 0);
          $encoder.alloc(32 - $fidl.kMessageHeaderSize);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_OnWithResponse_Type.response;
          $types[0].encode($encoder, $response, 0);
          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 _kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type.request;
          $decoder.claimMemory(16);
          final $async.Future<void> $future = impl.noRequestNoResponse();
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                  .request;
          $decoder.claimMemory(16);
          final $async.Future<void> $future = impl.noRequestEmptyResponse();
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal,
                $message.txid);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                  .request;
          $decoder.claimMemory(16);
          final $async.Future<String> $future = impl.noRequestWithResponse();
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal,
                $message.txid);
            $encoder.alloc(32 - $fidl.kMessageHeaderSize);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .response;
            $types[0].encode($encoder, $response, 0);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
                  .request;
          $decoder.claimMemory(32);
          final $async.Future<void> $future = impl.withRequestNoResponse(
            $types[0].decode($decoder, 0),
          );
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                  .request;
          $decoder.claimMemory(32);
          final $async.Future<void> $future = impl.withRequestEmptyResponse(
            $types[0].decode($decoder, 0),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal,
                $message.txid);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                  .request;
          $decoder.claimMemory(32);
          final $async.Future<String> $future = impl.withRequestWithResponse(
            $types[0].decode($decoder, 0),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
                $message.txid);
            $encoder.alloc(32 - $fidl.kMessageHeaderSize);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .response;
            $types[0].encode($encoder, $response, 0);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // 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 WithAndWithoutRequestResponseBinding');
    }
  }
}

// errorAsPrimitive: () -> ()
const int _kWithErrorSyntax_ErrorAsPrimitive_Ordinal = 0x7b58113900000000;
const $fidl.MethodType _kWithErrorSyntax_ErrorAsPrimitive_Type =
    $fidl.MethodType(
  request: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<WithErrorSyntaxErrorAsPrimitiveResult>(
        type: kWithErrorSyntax_ErrorAsPrimitive_Result_Type, offset: 16),
  ],
  name: r"WithErrorSyntax.ErrorAsPrimitive",
);
// errorAsEnum: () -> ()
const int _kWithErrorSyntax_ErrorAsEnum_Ordinal = 0x4c95de1f00000000;
const $fidl.MethodType _kWithErrorSyntax_ErrorAsEnum_Type = $fidl.MethodType(
  request: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<WithErrorSyntaxErrorAsEnumResult>(
        type: kWithErrorSyntax_ErrorAsEnum_Result_Type, offset: 16),
  ],
  name: r"WithErrorSyntax.ErrorAsEnum",
);

abstract class WithErrorSyntax extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => WithErrorSyntaxData();
  $async.Future<void> errorAsPrimitive();
  $async.Future<void> errorAsEnum();
}

class WithErrorSyntaxData implements $fidl.ServiceData<WithErrorSyntax> {
  const WithErrorSyntaxData();

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

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

class WithErrorSyntaxProxy extends $fidl.AsyncProxy<WithErrorSyntax>
    implements WithErrorSyntax {
  WithErrorSyntaxProxy()
      : super($fidl.AsyncProxyController<WithErrorSyntax>(
            $serviceName: null, $interfaceName: r'WithErrorSyntax')) {
    ctrl.onResponse = _handleResponse;
  }

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      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) {
      case _kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsPrimitive_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsPrimitive_Type.response;
          $decoder.claimMemory(24);
          // ignore: prefer_const_declarations
          final $response = $types[0].decode($decoder, 0);

          if ($response.tag ==
              WithErrorSyntaxErrorAsPrimitiveResultTag.response) {
            $completer.complete(null);
          } else {
            $completer.completeError($fidl.MethodException($response.err));
          }

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithErrorSyntax_ErrorAsEnum_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsEnum_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsEnum_Type.response;
          $decoder.claimMemory(24);
          // ignore: prefer_const_declarations
          final $response = $types[0].decode($decoder, 0);

          if ($response.tag == WithErrorSyntaxErrorAsEnumResultTag.response) {
            $completer.complete(null);
          } else {
            $completer.completeError($fidl.MethodException($response.err));
          }

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<void> errorAsPrimitive() 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(_kWithErrorSyntax_ErrorAsPrimitive_Ordinal, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> errorAsEnum() 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(_kWithErrorSyntax_ErrorAsEnum_Ordinal, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

class WithErrorSyntaxBinding extends $fidl.AsyncBinding<WithErrorSyntax> {
  WithErrorSyntaxBinding() : super(r"WithErrorSyntax");

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      case _kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsPrimitive_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsPrimitive_Type.request;
          $decoder.claimMemory(16);
          final $async.Future<void> $future = impl.errorAsPrimitive();
          $future.then(($responseValue) {
            return WithErrorSyntaxErrorAsPrimitiveResult.withResponse(
                WithErrorSyntaxErrorAsPrimitiveResponse());
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return WithErrorSyntaxErrorAsPrimitiveResult.withErr(
                  $error.value);
            } else {
              return Future.error($error);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsPrimitive_Ordinal, $message.txid);
            $encoder.alloc(24 - $fidl.kMessageHeaderSize);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsPrimitive_Type.response;
            $types[0].encode($encoder, $response, 0);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithErrorSyntax_ErrorAsEnum_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsEnum_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsEnum_Type.request;
          $decoder.claimMemory(16);
          final $async.Future<void> $future = impl.errorAsEnum();
          $future.then(($responseValue) {
            return WithErrorSyntaxErrorAsEnumResult.withResponse(
                WithErrorSyntaxErrorAsEnumResponse());
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return WithErrorSyntaxErrorAsEnumResult.withErr($error.value);
            } else {
              return Future.error($error);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsEnum_Ordinal, $message.txid);
            $encoder.alloc(24 - $fidl.kMessageHeaderSize);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsEnum_Type.response;
            $types[0].encode($encoder, $response, 0);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // 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 WithErrorSyntaxBinding');
    }
  }
}

// methodA: (int a, int b)
const int _kChannelProtocol_MethodA_Ordinal = 0x556693d200000000;
const $fidl.MethodType _kChannelProtocol_MethodA_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 16),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 24),
  ],
  response: null,
  name: r"ChannelProtocol.MethodA",
);
// eventA:  -> (int a, int b)
const int _kChannelProtocol_EventA_Ordinal = 0x1c78c20200000000;
const $fidl.MethodType _kChannelProtocol_EventA_Type = $fidl.MethodType(
  request: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 16),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 24),
  ],
  name: r"ChannelProtocol.EventA",
);
// methodB: (int a, int b) -> (int result)
const int _kChannelProtocol_MethodB_Ordinal = 0xac6551b00000000;
const $fidl.MethodType _kChannelProtocol_MethodB_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 16),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 24),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 16),
  ],
  name: r"ChannelProtocol.MethodB",
);
// mutateSocket: ($zx.Socket a) -> ($zx.Socket b)
const int _kChannelProtocol_MutateSocket_Ordinal = 0x4b02e28600000000;
const $fidl.MethodType _kChannelProtocol_MutateSocket_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$zx.Socket>(
        type: $fidl.SocketType(nullable: false), offset: 16),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<$zx.Socket>(
        type: $fidl.SocketType(nullable: false), offset: 16),
  ],
  name: r"ChannelProtocol.MutateSocket",
);

class ChannelProtocol$EventA$Response {
  final int a;
  final int b;
  ChannelProtocol$EventA$Response(
    this.a,
    this.b,
  );
}

abstract class ChannelProtocol extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => ChannelProtocolData();
  $async.Future<void> methodA(int a, int b);
  $async.Stream<ChannelProtocol$EventA$Response> get eventA;
  $async.Future<int> methodB(int a, int b);
  $async.Future<$zx.Socket> mutateSocket($zx.Socket a);
}

class ChannelProtocolData implements $fidl.ServiceData<ChannelProtocol> {
  const ChannelProtocolData();

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

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

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

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message);
    switch ($message.ordinal) {
      case _kChannelProtocol_EventA_Ordinal:
        final String _name = _kChannelProtocol_EventA_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_EventA_Type.response;
          $decoder.claimMemory(32);
          _eventAEventStreamController.add(ChannelProtocol$EventA$Response(
            $types[0].decode($decoder, 0),
            $types[1].decode($decoder, 0),
          ));
          // 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) {
      case _kChannelProtocol_MethodB_Ordinal:
        final String _name = _kChannelProtocol_MethodB_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_MethodB_Type.response;
          $decoder.claimMemory(24);
          // ignore: prefer_const_declarations
          final $response = $types[0].decode($decoder, 0);

          $completer.complete($response);

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kChannelProtocol_MutateSocket_Ordinal:
        final String _name = _kChannelProtocol_MutateSocket_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_MutateSocket_Type.response;
          $decoder.claimMemory(24);
          // ignore: prefer_const_declarations
          final $response = $types[0].decode($decoder, 0);

          $completer.complete($response);

          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<void> methodA(int a, int b) 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(_kChannelProtocol_MethodA_Ordinal, 0);
    $encoder.alloc(32 - $fidl.kMessageHeaderSize);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodA_Type.request;
    $types[0].encode($encoder, a, 0);
    $types[1].encode($encoder, b, 0);
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  final _eventAEventStreamController =
      $async.StreamController<ChannelProtocol$EventA$Response>.broadcast();
  @override
  $async.Stream<ChannelProtocol$EventA$Response> get eventA =>
      _eventAEventStreamController.stream;

  @override
  $async.Future<int> methodB(int a, int b) 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(_kChannelProtocol_MethodB_Ordinal, 0);
    $encoder.alloc(32 - $fidl.kMessageHeaderSize);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodB_Type.request;
    $types[0].encode($encoder, a, 0);
    $types[1].encode($encoder, b, 0);
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<$zx.Socket> mutateSocket($zx.Socket a) 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(_kChannelProtocol_MutateSocket_Ordinal, 0);
    $encoder.alloc(24 - $fidl.kMessageHeaderSize);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MutateSocket_Type.request;
    $types[0].encode($encoder, a, 0);
    final $completer = $async.Completer<$zx.Socket>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

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

          $types[0].encode($encoder, $response.a, 0);
          $types[1].encode($encoder, $response.b, 0);
          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 _kChannelProtocol_MethodA_Ordinal:
        final String _name = _kChannelProtocol_MethodA_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_MethodA_Type.request;
          $decoder.claimMemory(32);
          final $async.Future<void> $future = impl.methodA(
            $types[0].decode($decoder, 0),
            $types[1].decode($decoder, 0),
          );
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kChannelProtocol_MethodB_Ordinal:
        final String _name = _kChannelProtocol_MethodB_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_MethodB_Type.request;
          $decoder.claimMemory(32);
          final $async.Future<int> $future = impl.methodB(
            $types[0].decode($decoder, 0),
            $types[1].decode($decoder, 0),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kChannelProtocol_MethodB_Ordinal, $message.txid);
            $encoder.alloc(24 - $fidl.kMessageHeaderSize);
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_MethodB_Type.response;
            $types[0].encode($encoder, $response, 0);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kChannelProtocol_MutateSocket_Ordinal:
        final String _name = _kChannelProtocol_MutateSocket_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_MutateSocket_Type.request;
          $decoder.claimMemory(24);
          final $async.Future<$zx.Socket> $future = impl.mutateSocket(
            $types[0].decode($decoder, 0),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kChannelProtocol_MutateSocket_Ordinal, $message.txid);
            $encoder.alloc(24 - $fidl.kMessageHeaderSize);
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_MutateSocket_Type.response;
            $types[0].encode($encoder, $response, 0);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
          // 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 ChannelProtocolBinding');
    }
  }
}
