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

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;
  }

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

  @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.XUnionType<WithErrorSyntaxResponseAsStructResult>
    kWithErrorSyntax_ResponseAsStruct_Result_Type =
    $fidl.XUnionType<WithErrorSyntaxResponseAsStructResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ResponseAsStruct_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxResponseAsStructResult._ctor,
  nullable: false,
  flexible: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<WithErrorSyntaxResponseAsStructResult>
    kWithErrorSyntax_ResponseAsStruct_Result_OptType =
    $fidl.XUnionType<WithErrorSyntaxResponseAsStructResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ResponseAsStruct_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxResponseAsStructResult._ctor,
  nullable: true,
  flexible: 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;
  }

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

  @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.XUnionType<WithErrorSyntaxErrorAsPrimitiveResult>
    kWithErrorSyntax_ErrorAsPrimitive_Result_Type =
    $fidl.XUnionType<WithErrorSyntaxErrorAsPrimitiveResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsPrimitive_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxErrorAsPrimitiveResult._ctor,
  nullable: false,
  flexible: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<WithErrorSyntaxErrorAsPrimitiveResult>
    kWithErrorSyntax_ErrorAsPrimitive_Result_OptType =
    $fidl.XUnionType<WithErrorSyntaxErrorAsPrimitiveResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsPrimitive_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: WithErrorSyntaxErrorAsPrimitiveResult._ctor,
  nullable: true,
  flexible: 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;
  }

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

  @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.XUnionType<WithErrorSyntaxErrorAsEnumResult>
    kWithErrorSyntax_ErrorAsEnum_Result_Type =
    $fidl.XUnionType<WithErrorSyntaxErrorAsEnumResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsEnum_Response_Type,
    2: kErrorEnun_Type,
  },
  ctor: WithErrorSyntaxErrorAsEnumResult._ctor,
  nullable: false,
  flexible: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<WithErrorSyntaxErrorAsEnumResult>
    kWithErrorSyntax_ErrorAsEnum_Result_OptType =
    $fidl.XUnionType<WithErrorSyntaxErrorAsEnumResult>(
  members: <int, $fidl.FidlType>{
    1: kWithErrorSyntax_ErrorAsEnum_Response_Type,
    2: kErrorEnun_Type,
  },
  ctor: WithErrorSyntaxErrorAsEnumResult._ctor,
  nullable: true,
  flexible: 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: null,
  response: null,
  name: r"WithAndWithoutRequestResponse.NoRequestNoResponse",
  requestInlineSize: 0,
  responseInlineSize: 0,
);
// noRequestEmptyResponse: () -> ()
const int _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal =
    0x4068f26bf6d868ae;
const $fidl.MethodType
    _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type =
    $fidl.MethodType(
  request: null,
  response: null,
  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: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        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, nullable: false),
        offset: 0),
  ],
  response: null,
  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, nullable: false),
        offset: 0),
  ],
  response: null,
  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, nullable: false),
        offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        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: null,
  response: null,
  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: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null, nullable: false),
        offset: 0),
  ],
  name: r"WithAndWithoutRequestResponse.OnWithResponse",
  requestInlineSize: 0,
  responseInlineSize: 16,
);

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

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

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

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

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

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..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((_) {
      if (impl.onEmptyResponse != null) {
        $subscriptions.add(impl.onEmptyResponse.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);
        }));
      }
      if (impl.onWithResponse != null) {
        $subscriptions.add(impl.onWithResponse.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: null,
  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: null,
  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: null,
  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 extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => WithErrorSyntaxData();
  $async.Future<WithErrorSyntax$ResponseAsStruct$Response> responseAsStruct();
  $async.Future<void> errorAsPrimitive();
  $async.Future<void> errorAsEnum();
}

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

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

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

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

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..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: null,
  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: null,
  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,
);
// 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(nullable: false), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<$zircon.Socket>(
        type: $fidl.SocketType(nullable: false), 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 extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => ChannelProtocolData();
  $async.Future<void> methodA(int a, int b);
  $async.Stream<ChannelProtocol$EventA$Response> get eventA;
  $async.Future<int> methodB(int a, int b);
  $async.Future<$zircon.Socket> mutateSocket($zircon.Socket a);
}

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

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

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

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

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..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_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<$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((_) {
      if (impl.eventA != null) {
        $subscriptions.add(impl.eventA.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_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: null,
  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: null,
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"Transitional.Event",
  requestInlineSize: 0,
  responseInlineSize: 8,
);

abstract class Transitional extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $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();
  }
}

class TransitionalData implements $fidl.ServiceData<Transitional> {
  const TransitionalData();

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

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

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

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

  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((_) {
      if (impl.event != null) {
        $subscriptions.add(impl.event.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');
    }
  }
}
