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

library fidl_fidl_test_protocols_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

class ObjType extends $fidl.Enum {
  factory ObjType(int _v) {
    switch (_v) {
      case 0x0:
        return none;
      case 0xe:
        return socket;
      default:
        throw $fidl.FidlError('Invalid strict enum value: $_v',
            $fidl.FidlErrorCode.fidlInvalidEnumValue);
    }
  }
  static const ObjType none = ObjType._(0x0);
  static const ObjType socket = ObjType._(0xe);

  const ObjType._(this.$value);

  @override
  final int $value;

  static const Map<String, ObjType> $valuesMap = {
    r'none': none,
    r'socket': socket,
  };

  static const List<ObjType> $values = [
    none,
    socket,
  ];

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

  @override
  bool isUnknown() {
    return false;
  }

  @override
  String toString() {
    switch ($value) {
      case 0x0:
        return r'ObjType.none';
      case 0xe:
        return r'ObjType.socket';
      default:
        return r'ObjType.' '${$value}';
    }
  }

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

const $fidl.EnumType<ObjType> kobj_type_Type = $fidl.EnumType<ObjType>(
    type: $fidl.Uint32Type(),
    values: {0x0: null, 0xe: null},
    ctor: ObjType._ctor);

class ErrorEnun extends $fidl.Enum {
  factory ErrorEnun(int _v) {
    switch (_v) {
      case 0x1:
        return errFoo;
      case 0x2:
        return errBar;
      default:
        throw $fidl.FidlError('Invalid strict enum value: $_v',
            $fidl.FidlErrorCode.fidlInvalidEnumValue);
    }
  }
  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,
  ];

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

  @override
  bool isUnknown() {
    return false;
  }

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

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

const $fidl.EnumType<ErrorEnun> kErrorEnun_Type = $fidl.EnumType<ErrorEnun>(
    type: $fidl.Uint32Type(),
    values: {0x1: null, 0x2: null},
    ctor: ErrorEnun._ctor);

enum WithErrorSyntaxResponseAsStructResultTag {
  response, // 0x1
  err, // 0x2
}

const Map<int, WithErrorSyntaxResponseAsStructResultTag>
    _WithErrorSyntaxResponseAsStructResultTag_map = {
  1: WithErrorSyntaxResponseAsStructResultTag.response,
  2: WithErrorSyntaxResponseAsStructResultTag.err,
};

class WithErrorSyntaxResponseAsStructResult extends $fidl.XUnion {
  const WithErrorSyntaxResponseAsStructResult.withResponse(
      WithErrorSyntaxResponseAsStructResponse value)
      : _ordinal = 1,
        _data = value;

  const WithErrorSyntaxResponseAsStructResult.withErr(int value)
      : _ordinal = 2,
        _data = value;

  WithErrorSyntaxResponseAsStructResult._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  WithErrorSyntaxResponseAsStructResultTag get $tag =>
      _WithErrorSyntaxResponseAsStructResultTag_map[_ordinal]!;

  WithErrorSyntaxResponseAsStructResponse? get response {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  int? get err {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'WithErrorSyntaxResponseAsStructResult.response(' +
            response.toString() +
            ')';
      case 2:
        return r'WithErrorSyntaxResponseAsStructResult.err(' +
            err.toString() +
            ')';
      default:
        return r'WithErrorSyntaxResponseAsStructResult.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static WithErrorSyntaxResponseAsStructResult _ctor(int ordinal, Object data) {
    return WithErrorSyntaxResponseAsStructResult._(ordinal, data);
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<WithErrorSyntaxResponseAsStructResult>
    kWithErrorSyntax_ResponseAsStruct_Result_Type =
    $fidl.UnionType<WithErrorSyntaxResponseAsStructResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ResponseAsStruct_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxResponseAsStructResult._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<WithErrorSyntaxResponseAsStructResult>
    kWithErrorSyntax_ResponseAsStruct_Result_OptType =
    $fidl.NullableUnionType<WithErrorSyntaxResponseAsStructResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ResponseAsStruct_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxResponseAsStructResult._ctor,
  flexible: false,
  resource: false,
);

enum WithErrorSyntaxErrorAsPrimitiveResultTag {
  response, // 0x1
  err, // 0x2
}

const Map<int, WithErrorSyntaxErrorAsPrimitiveResultTag>
    _WithErrorSyntaxErrorAsPrimitiveResultTag_map = {
  1: WithErrorSyntaxErrorAsPrimitiveResultTag.response,
  2: WithErrorSyntaxErrorAsPrimitiveResultTag.err,
};

class WithErrorSyntaxErrorAsPrimitiveResult extends $fidl.XUnion {
  const WithErrorSyntaxErrorAsPrimitiveResult.withResponse(
      WithErrorSyntaxErrorAsPrimitiveResponse value)
      : _ordinal = 1,
        _data = value;

  const WithErrorSyntaxErrorAsPrimitiveResult.withErr(int value)
      : _ordinal = 2,
        _data = value;

  WithErrorSyntaxErrorAsPrimitiveResult._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  WithErrorSyntaxErrorAsPrimitiveResultTag get $tag =>
      _WithErrorSyntaxErrorAsPrimitiveResultTag_map[_ordinal]!;

  WithErrorSyntaxErrorAsPrimitiveResponse? get response {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  int? get err {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'WithErrorSyntaxErrorAsPrimitiveResult.response(' +
            response.toString() +
            ')';
      case 2:
        return r'WithErrorSyntaxErrorAsPrimitiveResult.err(' +
            err.toString() +
            ')';
      default:
        return r'WithErrorSyntaxErrorAsPrimitiveResult.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static WithErrorSyntaxErrorAsPrimitiveResult _ctor(int ordinal, Object data) {
    return WithErrorSyntaxErrorAsPrimitiveResult._(ordinal, data);
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<WithErrorSyntaxErrorAsPrimitiveResult>
    kWithErrorSyntax_ErrorAsPrimitive_Result_Type =
    $fidl.UnionType<WithErrorSyntaxErrorAsPrimitiveResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsPrimitive_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxErrorAsPrimitiveResult._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<WithErrorSyntaxErrorAsPrimitiveResult>
    kWithErrorSyntax_ErrorAsPrimitive_Result_OptType =
    $fidl.NullableUnionType<WithErrorSyntaxErrorAsPrimitiveResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsPrimitive_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxErrorAsPrimitiveResult._ctor,
  flexible: false,
  resource: false,
);

enum WithErrorSyntaxErrorAsEnumResultTag {
  response, // 0x1
  err, // 0x2
}

const Map<int, WithErrorSyntaxErrorAsEnumResultTag>
    _WithErrorSyntaxErrorAsEnumResultTag_map = {
  1: WithErrorSyntaxErrorAsEnumResultTag.response,
  2: WithErrorSyntaxErrorAsEnumResultTag.err,
};

class WithErrorSyntaxErrorAsEnumResult extends $fidl.XUnion {
  const WithErrorSyntaxErrorAsEnumResult.withResponse(
      WithErrorSyntaxErrorAsEnumResponse value)
      : _ordinal = 1,
        _data = value;

  const WithErrorSyntaxErrorAsEnumResult.withErr(ErrorEnun value)
      : _ordinal = 2,
        _data = value;

  WithErrorSyntaxErrorAsEnumResult._(int ordinal, Object data)
      : _ordinal = ordinal,
        _data = data;

  final int _ordinal;
  final _data;

  WithErrorSyntaxErrorAsEnumResultTag get $tag =>
      _WithErrorSyntaxErrorAsEnumResultTag_map[_ordinal]!;

  WithErrorSyntaxErrorAsEnumResponse? get response {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

  ErrorEnun? get err {
    if (_ordinal != 2) {
      return null;
    }
    return _data;
  }

  $fidl.UnknownRawData? get $unknownData {
    switch (_ordinal) {
      case 1:
      case 2:
        return null;
      default:
        return _data;
    }
  }

  @override
  String toString() {
    switch (_ordinal) {
      case 1:
        return r'WithErrorSyntaxErrorAsEnumResult.response(' +
            response.toString() +
            ')';
      case 2:
        return r'WithErrorSyntaxErrorAsEnumResult.err(' + err.toString() + ')';
      default:
        return r'WithErrorSyntaxErrorAsEnumResult.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

  static WithErrorSyntaxErrorAsEnumResult _ctor(int ordinal, Object data) {
    return WithErrorSyntaxErrorAsEnumResult._(ordinal, data);
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<WithErrorSyntaxErrorAsEnumResult>
    kWithErrorSyntax_ErrorAsEnum_Result_Type =
    $fidl.UnionType<WithErrorSyntaxErrorAsEnumResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsEnum_Response_Type,
    2: kErrorEnun_Type,
  },
  ctor: WithErrorSyntaxErrorAsEnumResult._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<WithErrorSyntaxErrorAsEnumResult>
    kWithErrorSyntax_ErrorAsEnum_Result_OptType =
    $fidl.NullableUnionType<WithErrorSyntaxErrorAsEnumResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsEnum_Response_Type,
    2: kErrorEnun_Type,
  },
  ctor: WithErrorSyntaxErrorAsEnumResult._ctor,
  flexible: false,
  resource: false,
);

class WithErrorSyntaxResponseAsStructResponse extends $fidl.Struct {
  const WithErrorSyntaxResponseAsStructResponse({
    required this.a,
    required this.b,
    required this.c,
  });
  WithErrorSyntaxResponseAsStructResponse.clone(
    WithErrorSyntaxResponseAsStructResponse $orig, {
    int? a,
    int? b,
    int? c,
  }) : this(
          a: a ?? $orig.a,
          b: b ?? $orig.b,
          c: c ?? $orig.c,
        );

  final int a;
  final int b;
  final int c;

  @override
  List<Object?> get $fields {
    return <Object?>[
      a,
      b,
      c,
    ];
  }

  static const $fieldType0 = $fidl.Int64Type();
  static const $fieldType1 = $fidl.Int64Type();
  static const $fieldType2 = $fidl.Int64Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, a, $offset + 0);
    $fieldType1.encode($encoder, b, $offset + 8);
    $fieldType2.encode($encoder, c, $offset + 16);
  }

  @override
  String toString() {
    return r'WithErrorSyntaxResponseAsStructResponse' r'(a: ' +
        a.toString() +
        r', b: ' +
        b.toString() +
        r', c: ' +
        c.toString() +
        r')';
  }

  static WithErrorSyntaxResponseAsStructResponse _structDecode(
      $fidl.Decoder $decoder, int $offset) {
    return WithErrorSyntaxResponseAsStructResponse(
        a: $fieldType0.decode($decoder, $offset + 0),
        b: $fieldType1.decode($decoder, $offset + 8),
        c: $fieldType2.decode($decoder, $offset + 16));
  }
}

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<WithErrorSyntaxResponseAsStructResponse>
    kWithErrorSyntax_ResponseAsStruct_Response_Type =
    $fidl.StructType<WithErrorSyntaxResponseAsStructResponse>(
  inlineSize: 24,
  structDecode: WithErrorSyntaxResponseAsStructResponse._structDecode,
);

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

  final int reserved;

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

  static const $fieldType0 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, reserved, $offset + 0);
  }

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<WithErrorSyntaxErrorAsPrimitiveResponse>
    kWithErrorSyntax_ErrorAsPrimitive_Response_Type =
    $fidl.StructType<WithErrorSyntaxErrorAsPrimitiveResponse>(
  inlineSize: 1,
  structDecode: WithErrorSyntaxErrorAsPrimitiveResponse._structDecode,
);

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

  final int reserved;

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

  static const $fieldType0 = $fidl.Uint8Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, reserved, $offset + 0);
  }

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

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<WithErrorSyntaxErrorAsEnumResponse>
    kWithErrorSyntax_ErrorAsEnum_Response_Type =
    $fidl.StructType<WithErrorSyntaxErrorAsEnumResponse>(
  inlineSize: 1,
  structDecode: WithErrorSyntaxErrorAsEnumResponse._structDecode,
);

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

// noRequestNoResponse: ()
const int _kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal =
    0x6ad894147d0c6ba4;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type = $fidl.MethodType(
  request: [],
  response: [],
  name: r"WithAndWithoutRequestResponse.NoRequestNoResponse",
  requestInlineSize: 0,
  responseInlineSize: 0,
);
// noRequestEmptyResponse: () -> ()
const int _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal =
    0x4068f26bf6d868ae;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type =
    $fidl.MethodType(
  request: [],
  response: [],
  name: r"WithAndWithoutRequestResponse.NoRequestEmptyResponse",
  requestInlineSize: 0,
  responseInlineSize: 0,
);
// noRequestWithResponse: () -> (String ret)
const int _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal =
    0x447e655905ccfbf4;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type =
    $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  name: r"WithAndWithoutRequestResponse.NoRequestWithResponse",
  requestInlineSize: 0,
  responseInlineSize: 16,
);
// withRequestNoResponse: (String arg)
const int _kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal =
    0x7cb47b2f9e76d17d;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  response: [],
  name: r"WithAndWithoutRequestResponse.WithRequestNoResponse",
  requestInlineSize: 16,
  responseInlineSize: 0,
);
// withRequestEmptyResponse: (String arg) -> ()
const int _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal =
    0x65eb512ff0e1c07e;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  response: [],
  name: r"WithAndWithoutRequestResponse.WithRequestEmptyResponse",
  requestInlineSize: 16,
  responseInlineSize: 0,
);
// withRequestWithResponse: (String arg) -> (String ret)
const int _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal =
    0x1d323510d4447cf1;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  name: r"WithAndWithoutRequestResponse.WithRequestWithResponse",
  requestInlineSize: 16,
  responseInlineSize: 16,
);
// onEmptyResponse:  -> ()
const int _kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal =
    0x125c87a592bff029;
const $fidl.MethodType _kWithAndWithoutRequestResponse_OnEmptyResponse_Type =
    $fidl.MethodType(
  request: [],
  response: [],
  name: r"WithAndWithoutRequestResponse.OnEmptyResponse",
  requestInlineSize: 0,
  responseInlineSize: 0,
);
// onWithResponse:  -> (String ret)
const int _kWithAndWithoutRequestResponse_OnWithResponse_Ordinal =
    0x177adc0a3ee346c2;
const $fidl.MethodType _kWithAndWithoutRequestResponse_OnWithResponse_Type =
    $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  name: r"WithAndWithoutRequestResponse.OnWithResponse",
  requestInlineSize: 0,
  responseInlineSize: 16,
);

abstract class WithAndWithoutRequestResponse {
  $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;
}

// TODO: Remove ServiceData for non-service
class WithAndWithoutRequestResponseData
    implements $fidl.ServiceData<WithAndWithoutRequestResponse> {
  const WithAndWithoutRequestResponseData();

  @override
  String getName() {
    return "";
  }

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

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

  void _handleEvent($fidl.Message $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!;
          _onEmptyResponseEventStreamController.add(null);
        } 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!;
          _onWithResponseEventStreamController.add($fidl.decodeMessage(
              $message,
              _kWithAndWithoutRequestResponse_OnWithResponse_Type
                  .decodeResponseInlineSize(),
              $types[0]));
        } 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;
    }
    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!;
          // ignore: prefer_const_declarations
          final $response = null;

          $completer.complete($response);
        } 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!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                  .decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } 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!;
          // ignore: prefer_const_declarations
          final $response = null;

          $completer.complete($response);
        } 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!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                  .decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } 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);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
            .encodingRequestInlineSize(), () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize);
    });
    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);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
            .encodingRequestInlineSize(), () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize);
    });
    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);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
            .encodingRequestInlineSize(), () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize);
    });
    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((_) {
      final impl = this.impl;
      if (impl != null) {
        final _onEmptyResponse_stream = impl.onEmptyResponse;
        if (_onEmptyResponse_stream != null) {
          $subscriptions.add(_onEmptyResponse_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal, 0);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_OnEmptyResponse_Type.response!;

            sendMessage($encoder.message);
          }));
        }
        final _onWithResponse_stream = impl.onWithResponse;
        if (_onWithResponse_stream != null) {
          $subscriptions.add(_onWithResponse_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_OnWithResponse_Ordinal, 0);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_OnWithResponse_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithAndWithoutRequestResponse_OnWithResponse_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.noRequestNoResponse();
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _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');
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<String> $future = $fidl
              .decodeMessageWithCallback<$async.Future<String>>(
                  $message,
                  _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.noRequestWithResponse();
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal,
                $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.withRequestNoResponse(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.withRequestEmptyResponse(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $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');
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<String> $future = $fidl
              .decodeMessageWithCallback<$async.Future<String>>(
                  $message,
                  _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.withRequestWithResponse(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
                $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } 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');
    }
  }
}

// responseAsStruct: () -> (int a, int b, int c)
const int _kWithErrorSyntax_ResponseAsStruct_Ordinal = 0x3784d38864674290;
const $fidl.MethodType _kWithErrorSyntax_ResponseAsStruct_Type =
    $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<WithErrorSyntaxResponseAsStructResult>(
        type: kWithErrorSyntax_ResponseAsStruct_Result_Type, offset: 0),
  ],
  name: r"WithErrorSyntax.ResponseAsStruct",
  requestInlineSize: 0,
  responseInlineSize: 24,
);
// errorAsPrimitive: () -> ()
const int _kWithErrorSyntax_ErrorAsPrimitive_Ordinal = 0x2f7c390f3cdef4ce;
const $fidl.MethodType _kWithErrorSyntax_ErrorAsPrimitive_Type =
    $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<WithErrorSyntaxErrorAsPrimitiveResult>(
        type: kWithErrorSyntax_ErrorAsPrimitive_Result_Type, offset: 0),
  ],
  name: r"WithErrorSyntax.ErrorAsPrimitive",
  requestInlineSize: 0,
  responseInlineSize: 24,
);
// errorAsEnum: () -> ()
const int _kWithErrorSyntax_ErrorAsEnum_Ordinal = 0x8b550d7c29f740c;
const $fidl.MethodType _kWithErrorSyntax_ErrorAsEnum_Type = $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<WithErrorSyntaxErrorAsEnumResult>(
        type: kWithErrorSyntax_ErrorAsEnum_Result_Type, offset: 0),
  ],
  name: r"WithErrorSyntax.ErrorAsEnum",
  requestInlineSize: 0,
  responseInlineSize: 24,
);

class WithErrorSyntax$ResponseAsStruct$Response {
  final int a;
  final int b;
  final int c;
  WithErrorSyntax$ResponseAsStruct$Response(
    this.a,
    this.b,
    this.c,
  );
}

abstract class WithErrorSyntax {
  $fidl.ServiceData? get $serviceData => WithErrorSyntaxData();
  $async.Future<WithErrorSyntax$ResponseAsStruct$Response> responseAsStruct();
  $async.Future<void> errorAsPrimitive();
  $async.Future<void> errorAsEnum();
}

// TODO: Remove ServiceData for non-service
class WithErrorSyntaxData implements $fidl.ServiceData<WithErrorSyntax> {
  const WithErrorSyntaxData();

  @override
  String getName() {
    return "";
  }

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

class WithErrorSyntaxProxy extends $fidl.AsyncProxy<WithErrorSyntax>
    implements WithErrorSyntax {
  WithErrorSyntaxProxy()
      : super($fidl.AsyncProxyController<WithErrorSyntax>(
            $interfaceName: r'WithErrorSyntax')) {
    ctrl.onResponse = _handleResponse;
  }
  @override
  Null get $serviceData => null;

  void _handleEvent($fidl.Message $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;
    }
    switch ($message.ordinal) {
      case _kWithErrorSyntax_ResponseAsStruct_Ordinal:
        final String _name = _kWithErrorSyntax_ResponseAsStruct_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ResponseAsStruct_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kWithErrorSyntax_ResponseAsStruct_Type
                  .decodeResponseInlineSize(),
              $types[0]);

          if ($response.$tag ==
              WithErrorSyntaxResponseAsStructResultTag.response) {
            $completer.complete(WithErrorSyntax$ResponseAsStruct$Response(
              $response.response.a,
              $response.response.b,
              $response.response.c,
            ));
          } else {
            $completer.completeError($fidl.MethodException($response.err));
          }
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsPrimitive_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsPrimitive_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kWithErrorSyntax_ErrorAsPrimitive_Type
                  .decodeResponseInlineSize(),
              $types[0]);

          if ($response.$tag ==
              WithErrorSyntaxErrorAsPrimitiveResultTag.response) {
            $completer.complete(null);
          } else {
            $completer.completeError($fidl.MethodException($response.err));
          }
        } 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!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kWithErrorSyntax_ErrorAsEnum_Type.decodeResponseInlineSize(),
              $types[0]);

          if ($response.$tag == WithErrorSyntaxErrorAsEnumResultTag.response) {
            $completer.complete(null);
          } else {
            $completer.completeError($fidl.MethodException($response.err));
          }
        } 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<WithErrorSyntax$ResponseAsStruct$Response>
      responseAsStruct() 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_ResponseAsStruct_Ordinal, 0);
    final $completer =
        $async.Completer<WithErrorSyntax$ResponseAsStruct$Response>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @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) {
    switch ($message.ordinal) {
      case _kWithErrorSyntax_ResponseAsStruct_Ordinal:
        final String _name = _kWithErrorSyntax_ResponseAsStruct_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ResponseAsStruct_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<WithErrorSyntax$ResponseAsStruct$Response>
              $future = $fidl.decodeMessageWithCallback<
                      $async.Future<WithErrorSyntax$ResponseAsStruct$Response>>(
                  $message,
                  _kWithErrorSyntax_ResponseAsStruct_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.responseAsStruct();
          });
          $future.then(($responseValue) {
            return WithErrorSyntaxResponseAsStructResult.withResponse(
                WithErrorSyntaxResponseAsStructResponse(
              a: $responseValue.a,
              b: $responseValue.b,
              c: $responseValue.c,
            ));
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return WithErrorSyntaxResponseAsStructResult.withErr(
                  $error.value);
            } else {
              return Future.error($error, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ResponseAsStruct_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ResponseAsStruct_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithErrorSyntax_ResponseAsStruct_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsPrimitive_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsPrimitive_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithErrorSyntax_ErrorAsPrimitive_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _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, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsPrimitive_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsPrimitive_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithErrorSyntax_ErrorAsPrimitive_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kWithErrorSyntax_ErrorAsEnum_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _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, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsEnum_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsEnum_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithErrorSyntax_ErrorAsEnum_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } 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 = 0x7d92c10fb2d002e;
const $fidl.MethodType _kChannelProtocol_MethodA_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 8),
  ],
  response: [],
  name: r"ChannelProtocol.MethodA",
  requestInlineSize: 16,
  responseInlineSize: 0,
);
// eventA:  -> (int a, int b)
const int _kChannelProtocol_EventA_Ordinal = 0x52c2fa481a687dfa;
const $fidl.MethodType _kChannelProtocol_EventA_Type = $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 8),
  ],
  name: r"ChannelProtocol.EventA",
  requestInlineSize: 0,
  responseInlineSize: 16,
);
// methodB: (int a, int b) -> (int result)
const int _kChannelProtocol_MethodB_Ordinal = 0x5da1d2ed00055cea;
const $fidl.MethodType _kChannelProtocol_MethodB_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 8),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"ChannelProtocol.MethodB",
  requestInlineSize: 16,
  responseInlineSize: 8,
);
// takeHandle: ($zircon.Handle h) -> ()
const int _kChannelProtocol_TakeHandle_Ordinal = 0xc25674355065c28;
const $fidl.MethodType _kChannelProtocol_TakeHandle_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$zircon.Handle>(type: $fidl.HandleType(), offset: 0),
  ],
  response: [],
  name: r"ChannelProtocol.TakeHandle",
  requestInlineSize: 8,
  responseInlineSize: 0,
);
// mutateSocket: ($zircon.Socket a) -> ($zircon.Socket b)
const int _kChannelProtocol_MutateSocket_Ordinal = 0x7dd036a18b33b76a;
const $fidl.MethodType _kChannelProtocol_MutateSocket_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$zircon.Socket>(type: $fidl.SocketType(), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<$zircon.Socket>(type: $fidl.SocketType(), offset: 0),
  ],
  name: r"ChannelProtocol.MutateSocket",
  requestInlineSize: 8,
  responseInlineSize: 8,
);

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

abstract class ChannelProtocol {
  $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<void> takeHandle($zircon.Handle h);
  $async.Future<$zircon.Socket> mutateSocket($zircon.Socket a);
}

// TODO: Remove ServiceData for non-service
class ChannelProtocolData implements $fidl.ServiceData<ChannelProtocol> {
  const ChannelProtocolData();

  @override
  String getName() {
    return "";
  }

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

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

  void _handleEvent($fidl.Message $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!;
          _eventAEventStreamController.add($fidl
              .decodeMessageWithCallback<ChannelProtocol$EventA$Response>(
                  $message,
                  _kChannelProtocol_EventA_Type.decodeResponseInlineSize(),
                  ($fidl.Decoder decoder) {
            return ChannelProtocol$EventA$Response(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
              $types[1].decode(decoder, $fidl.kMessageHeaderSize),
            );
          }));
        } 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;
    }
    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!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kChannelProtocol_MethodB_Type.decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kChannelProtocol_TakeHandle_Ordinal:
        final String _name = _kChannelProtocol_TakeHandle_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_TakeHandle_Type.response!;
          // ignore: prefer_const_declarations
          final $response = null;

          $completer.complete($response);
        } 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!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kChannelProtocol_MutateSocket_Type.decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } 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);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodA_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChannelProtocol_MethodA_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize);
      $types[1].encode($encoder, b, $fidl.kMessageHeaderSize);
    });
    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);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodB_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChannelProtocol_MethodB_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize);
      $types[1].encode($encoder, b, $fidl.kMessageHeaderSize);
    });
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> takeHandle($zircon.Handle h) 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_TakeHandle_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_TakeHandle_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChannelProtocol_TakeHandle_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, h, $fidl.kMessageHeaderSize);
    });
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<$zircon.Socket> mutateSocket($zircon.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);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MutateSocket_Type.request!;
    $fidl.encodeMessageWithCallback($encoder,
        _kChannelProtocol_MutateSocket_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize);
    });
    final $completer = $async.Completer<$zircon.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((_) {
      final impl = this.impl;
      if (impl != null) {
        final _eventA_stream = impl.eventA;
        if (_eventA_stream != null) {
          $subscriptions.add(_eventA_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kChannelProtocol_EventA_Ordinal, 0);
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_EventA_Type.response!;
            $fidl.encodeMessageWithCallback($encoder,
                _kChannelProtocol_EventA_Type.encodingResponseInlineSize(), () {
              $types[0].encode($encoder, $response.a, $fidl.kMessageHeaderSize);
              $types[1].encode($encoder, $response.b, $fidl.kMessageHeaderSize);
            });
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kChannelProtocol_MethodA_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.methodA(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
              $types[1].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<int> $future = $fidl
              .decodeMessageWithCallback<$async.Future<int>>($message,
                  _kChannelProtocol_MethodB_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.methodB(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
              $types[1].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kChannelProtocol_MethodB_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_MethodB_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kChannelProtocol_MethodB_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kChannelProtocol_TakeHandle_Ordinal:
        final String _name = _kChannelProtocol_TakeHandle_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_TakeHandle_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kChannelProtocol_TakeHandle_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.takeHandle(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kChannelProtocol_TakeHandle_Ordinal, $message.txid);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } 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!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<$zircon.Socket> $future = $fidl
              .decodeMessageWithCallback<$async.Future<$zircon.Socket>>(
                  $message,
                  _kChannelProtocol_MutateSocket_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.mutateSocket(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kChannelProtocol_MutateSocket_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_MutateSocket_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kChannelProtocol_MutateSocket_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } 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');
    }
  }
}

// request: (int x) -> (int y)
const int _kTransitional_Request_Ordinal = 0x62d345e621780ee8;
const $fidl.MethodType _kTransitional_Request_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"Transitional.Request",
  requestInlineSize: 8,
  responseInlineSize: 8,
);
// oneWay: (int x)
const int _kTransitional_OneWay_Ordinal = 0xf99bc4b26bc9ea5;
const $fidl.MethodType _kTransitional_OneWay_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  response: [],
  name: r"Transitional.OneWay",
  requestInlineSize: 8,
  responseInlineSize: 0,
);
// event:  -> (int x)
const int _kTransitional_Event_Ordinal = 0x53bb9212bcbe8966;
const $fidl.MethodType _kTransitional_Event_Type = $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"Transitional.Event",
  requestInlineSize: 0,
  responseInlineSize: 8,
);

abstract class Transitional {
  $fidl.ServiceData? get $serviceData => TransitionalData();
  $async.Future<int> request(int x) {
    return $async.Future.error(UnimplementedError(), StackTrace.current);
  }

  $async.Future<void> oneWay(int x) {
    return $async.Future.error(UnimplementedError(), StackTrace.current);
  }

  $async.Stream<int>? get event {
    return $async.Stream.empty();
  }
}

// TODO: Remove ServiceData for non-service
class TransitionalData implements $fidl.ServiceData<Transitional> {
  const TransitionalData();

  @override
  String getName() {
    return "";
  }

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

class TransitionalProxy extends $fidl.AsyncProxy<Transitional>
    implements Transitional {
  TransitionalProxy()
      : super($fidl.AsyncProxyController<Transitional>(
            $interfaceName: r'Transitional')) {
    ctrl.onResponse = _handleResponse;
    ctrl.whenClosed.then((_) {
      _eventEventStreamController.close();
    }, onError: (_) {});
  }
  @override
  Null get $serviceData => null;

  void _handleEvent($fidl.Message $message) {
    switch ($message.ordinal) {
      case _kTransitional_Event_Ordinal:
        final String _name = _kTransitional_Event_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTransitional_Event_Type.response!;
          _eventEventStreamController.add($fidl.decodeMessage($message,
              _kTransitional_Event_Type.decodeResponseInlineSize(), $types[0]));
        } 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;
    }
    switch ($message.ordinal) {
      case _kTransitional_Request_Ordinal:
        final String _name = _kTransitional_Request_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTransitional_Request_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kTransitional_Request_Type.decodeResponseInlineSize(),
              $types[0]);

          $completer.complete($response);
        } 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<int> request(int x) 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(_kTransitional_Request_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kTransitional_Request_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kTransitional_Request_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, x, $fidl.kMessageHeaderSize);
    });
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> oneWay(int x) 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(_kTransitional_OneWay_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kTransitional_OneWay_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kTransitional_OneWay_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, x, $fidl.kMessageHeaderSize);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  final _eventEventStreamController = $async.StreamController<int>.broadcast();
  @override
  $async.Stream<int> get event => _eventEventStreamController.stream;
}

class TransitionalBinding extends $fidl.AsyncBinding<Transitional> {
  TransitionalBinding() : super(r"Transitional") {
    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 _event_stream = impl.event;
        if (_event_stream != null) {
          $subscriptions.add(_event_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kTransitional_Event_Ordinal, 0);
            final List<$fidl.MemberType> $types =
                _kTransitional_Event_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kTransitional_Event_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    switch ($message.ordinal) {
      case _kTransitional_Request_Ordinal:
        final String _name = _kTransitional_Request_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTransitional_Request_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<int> $future = $fidl
              .decodeMessageWithCallback<$async.Future<int>>($message,
                  _kTransitional_Request_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.request(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kTransitional_Request_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kTransitional_Request_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kTransitional_Request_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kTransitional_OneWay_Ordinal:
        final String _name = _kTransitional_OneWay_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTransitional_OneWay_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kTransitional_OneWay_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.oneWay(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for TransitionalBinding');
    }
  }
}
