// 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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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(
              _kWithAndWithoutRequestResponse_OnEmptyResponse_Type
                  .decodeResponseInlineSize($decoder));
          _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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_OnWithResponse_Type
                  .decodeResponseInlineSize($decoder));
          _onWithResponseEventStreamController
              .add($types[0].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;
    }
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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(
              _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                  .decodeResponseInlineSize($decoder));
          // 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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                  .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                  .decodeResponseInlineSize($decoder));
          // 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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                  .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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);
    $encoder.alloc(_kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
        .encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type.request!;
    $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);
    $encoder.alloc(_kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
        .encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.request!;
    $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);
    $encoder.alloc(_kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
        .encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.request!;
    $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);
            $encoder.alloc(_kWithAndWithoutRequestResponse_OnEmptyResponse_Type
                .encodingResponseInlineSize($encoder));
            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);
            $encoder.alloc(_kWithAndWithoutRequestResponse_OnWithResponse_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_OnWithResponse_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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(
              _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type
                  .decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                  .decodeRequestInlineSize($decoder));
          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');
          });
        } 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(
              _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                  .decodeRequestInlineSize($decoder));
          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(
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
                  .decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                  .decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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!;
          $decoder.claimMemory(
              _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                  .decodeRequestInlineSize($decoder));
          final $async.Future<String> $future = impl!.withRequestWithResponse(
            $types[0].decode($decoder, $fidl.kMessageHeaderSize),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
                $message.txid);
            $encoder.alloc(
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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)
      ..claimMemory($fidl.kMessageHeaderSize);
    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!;
          $decoder.claimMemory(_kWithErrorSyntax_ResponseAsStruct_Type
              .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          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!;
          $decoder.claimMemory(_kWithErrorSyntax_ErrorAsPrimitive_Type
              .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          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!;
          $decoder.claimMemory(_kWithErrorSyntax_ErrorAsEnum_Type
              .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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!;
          $decoder.claimMemory(_kWithErrorSyntax_ResponseAsStruct_Type
              .decodeRequestInlineSize($decoder));
          final $async.Future<WithErrorSyntax$ResponseAsStruct$Response>
              $future = 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);
            $encoder.alloc(_kWithErrorSyntax_ResponseAsStruct_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ResponseAsStruct_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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!;
          $decoder.claimMemory(_kWithErrorSyntax_ErrorAsPrimitive_Type
              .decodeRequestInlineSize($decoder));
          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, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsPrimitive_Ordinal, $message.txid);
            $encoder.alloc(_kWithErrorSyntax_ErrorAsPrimitive_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsPrimitive_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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!;
          $decoder.claimMemory(_kWithErrorSyntax_ErrorAsEnum_Type
              .decodeRequestInlineSize($decoder));
          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, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsEnum_Ordinal, $message.txid);
            $encoder.alloc(_kWithErrorSyntax_ErrorAsEnum_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsEnum_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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(
              _kChannelProtocol_EventA_Type.decodeResponseInlineSize($decoder));
          _eventAEventStreamController.add(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;
    }
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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(_kChannelProtocol_MethodB_Type
              .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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!;
          $decoder.claimMemory(_kChannelProtocol_TakeHandle_Type
              .decodeResponseInlineSize($decoder));
          // 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!;
          $decoder.claimMemory(_kChannelProtocol_MutateSocket_Type
              .decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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);
    $encoder.alloc(
        _kChannelProtocol_MethodA_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodA_Type.request!;
    $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);
    $encoder.alloc(
        _kChannelProtocol_MethodB_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodB_Type.request!;
    $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);
    $encoder.alloc(
        _kChannelProtocol_TakeHandle_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_TakeHandle_Type.request!;
    $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);
    $encoder.alloc(_kChannelProtocol_MutateSocket_Type
        .encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MutateSocket_Type.request!;
    $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);
            $encoder.alloc(_kChannelProtocol_EventA_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_EventA_Type.response!;

            $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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(
              _kChannelProtocol_MethodA_Type.decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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!;
          $decoder.claimMemory(
              _kChannelProtocol_MethodB_Type.decodeRequestInlineSize($decoder));
          final $async.Future<int> $future = 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);
            $encoder.alloc(_kChannelProtocol_MethodB_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_MethodB_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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!;
          $decoder.claimMemory(_kChannelProtocol_TakeHandle_Type
              .decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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!;
          $decoder.claimMemory(_kChannelProtocol_MutateSocket_Type
              .decodeRequestInlineSize($decoder));
          final $async.Future<$zircon.Socket> $future = impl!.mutateSocket(
            $types[0].decode($decoder, $fidl.kMessageHeaderSize),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kChannelProtocol_MutateSocket_Ordinal, $message.txid);
            $encoder.alloc(_kChannelProtocol_MutateSocket_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_MutateSocket_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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!;
          $decoder.claimMemory(
              _kTransitional_Event_Type.decodeResponseInlineSize($decoder));
          _eventEventStreamController
              .add($types[0].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;
    }
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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!;
          $decoder.claimMemory(
              _kTransitional_Request_Type.decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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);
    $encoder
        .alloc(_kTransitional_Request_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kTransitional_Request_Type.request!;
    $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);
    $encoder
        .alloc(_kTransitional_OneWay_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kTransitional_OneWay_Type.request!;
    $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);
            $encoder.alloc(
                _kTransitional_Event_Type.encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kTransitional_Event_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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!;
          $decoder.claimMemory(
              _kTransitional_Request_Type.decodeRequestInlineSize($decoder));
          final $async.Future<int> $future = impl!.request(
            $types[0].decode($decoder, $fidl.kMessageHeaderSize),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kTransitional_Request_Ordinal, $message.txid);
            $encoder.alloc(_kTransitional_Request_Type
                .encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types =
                _kTransitional_Request_Type.response!;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $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!;
          $decoder.claimMemory(
              _kTransitional_OneWay_Type.decodeRequestInlineSize($decoder));
          final $async.Future<void> $future = 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');
    }
  }
}
