// 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, int $depth) {
    $fieldType0.encode($encoder, a, $offset + 0, $depth);
    $fieldType1.encode($encoder, b, $offset + 8, $depth);
    $fieldType2.encode($encoder, c, $offset + 16, $depth);
  }

  @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, int $depth) {
    return WithErrorSyntaxResponseAsStructResponse(
        a: $fieldType0.decode($decoder, $offset + 0, $depth),
        b: $fieldType1.decode($decoder, $offset + 8, $depth),
        c: $fieldType2.decode($decoder, $offset + 16, $depth));
  }
}

// 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, int $depth) {
    $fieldType0.encode($encoder, reserved, $offset + 0, $depth);
  }

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

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

// 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, int $depth) {
    $fieldType0.encode($encoder, reserved, $offset + 0, $depth);
  }

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

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

// 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.IncomingMessage $message) {
    switch ($message.ordinal) {
      case _kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_OnEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_OnEmptyResponse_Type.response!;
          _onEmptyResponseEventStreamController.add(null);
        } catch (_e) {
          ctrl.proxyError(
              $fidl.FidlError('Exception handling event $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_OnWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_OnWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_OnWithResponse_Type.response!;
          _onWithResponseEventStreamController.add($fidl.decodeMessage(
              $message,
              _kWithAndWithoutRequestResponse_OnWithResponse_Type
                  .decodeResponseInlineSize(),
              $types[0]));
        } catch (_e) {
          ctrl.proxyError(
              $fidl.FidlError('Exception handling event $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.IncomingMessage $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    switch ($message.ordinal) {
      case _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                  .response!;
          // ignore: prefer_const_declarations
          final $response = null;

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

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

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

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

  @override
  $async.Future<void> noRequestNoResponse() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal, 0);
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  @override
  $async.Future<void> noRequestEmptyResponse() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<String> noRequestWithResponse() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal, 0);
    final $completer = $async.Completer<String>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> withRequestNoResponse(String arg) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
            .encodingRequestInlineSize(), () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize, 1);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  @override
  $async.Future<void> withRequestEmptyResponse(String arg) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
            .encodingRequestInlineSize(), () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<String> withRequestWithResponse(String arg) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
            .encodingRequestInlineSize(), () {
      $types[0].encode($encoder, arg, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<String>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

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

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

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

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

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

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_NoRequestNoResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.noRequestNoResponse();
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.noRequestEmptyResponse();
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal,
                $message.txid);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<String> $future = $fidl
              .decodeMessageWithCallback<$async.Future<String>>(
                  $message,
                  _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.noRequestWithResponse();
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal,
                $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithAndWithoutRequestResponse_NoRequestWithResponse_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_WithRequestNoResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.withRequestNoResponse(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.withRequestEmptyResponse(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal,
                $message.txid);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal:
        final String _name =
            _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                  .request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<String> $future = $fidl
              .decodeMessageWithCallback<$async.Future<String>>(
                  $message,
                  _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.withRequestWithResponse(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal,
                $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithAndWithoutRequestResponse_WithRequestWithResponse_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for WithAndWithoutRequestResponseBinding');
    }
  }
}

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

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

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

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

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

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

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

  void _handleEvent($fidl.IncomingMessage $message) {
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.IncomingMessage $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    switch ($message.ordinal) {
      case _kWithErrorSyntax_ResponseAsStruct_Ordinal:
        final String _name = _kWithErrorSyntax_ResponseAsStruct_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ResponseAsStruct_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kWithErrorSyntax_ResponseAsStruct_Type
                  .decodeResponseInlineSize(),
              $types[0]);

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

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

          if ($response.$tag == WithErrorSyntaxErrorAsEnumResultTag.response) {
            $completer.complete(null);
          } else {
            $completer.completeError($fidl.MethodException($response.err));
          }
        } catch (_e) {
          ctrl.proxyError($fidl.FidlError(
              'Exception handling method response $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<WithErrorSyntax$ResponseAsStruct$Response>
      responseAsStruct() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kWithErrorSyntax_ResponseAsStruct_Ordinal, 0);
    final $completer =
        $async.Completer<WithErrorSyntax$ResponseAsStruct$Response>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> errorAsPrimitive() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kWithErrorSyntax_ErrorAsPrimitive_Ordinal, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> errorAsEnum() async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kWithErrorSyntax_ErrorAsEnum_Ordinal, 0);
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kWithErrorSyntax_ResponseAsStruct_Ordinal:
        final String _name = _kWithErrorSyntax_ResponseAsStruct_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ResponseAsStruct_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<WithErrorSyntax$ResponseAsStruct$Response>
              $future = $fidl.decodeMessageWithCallback<
                      $async.Future<WithErrorSyntax$ResponseAsStruct$Response>>(
                  $message,
                  _kWithErrorSyntax_ResponseAsStruct_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.responseAsStruct();
          });
          $future.then(($responseValue) {
            return WithErrorSyntaxResponseAsStructResult.withResponse(
                WithErrorSyntaxResponseAsStructResponse(
              a: $responseValue.a,
              b: $responseValue.b,
              c: $responseValue.c,
            ));
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return WithErrorSyntaxResponseAsStructResult.withErr(
                  $error.value);
            } else {
              return Future.error($error, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ResponseAsStruct_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ResponseAsStruct_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithErrorSyntax_ResponseAsStruct_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithErrorSyntax_ErrorAsPrimitive_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsPrimitive_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsPrimitive_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message,
                  _kWithErrorSyntax_ErrorAsPrimitive_Type
                      .decodeRequestInlineSize(), ($fidl.Decoder decoder) {
            return _impl.errorAsPrimitive();
          });
          $future.then(($responseValue) {
            return WithErrorSyntaxErrorAsPrimitiveResult.withResponse(
                WithErrorSyntaxErrorAsPrimitiveResponse());
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return WithErrorSyntaxErrorAsPrimitiveResult.withErr(
                  $error.value);
            } else {
              return Future.error($error, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsPrimitive_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsPrimitive_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithErrorSyntax_ErrorAsPrimitive_Type
                    .encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kWithErrorSyntax_ErrorAsEnum_Ordinal:
        final String _name = _kWithErrorSyntax_ErrorAsEnum_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kWithErrorSyntax_ErrorAsEnum_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kWithErrorSyntax_ErrorAsEnum_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.errorAsEnum();
          });
          $future.then(($responseValue) {
            return WithErrorSyntaxErrorAsEnumResult.withResponse(
                WithErrorSyntaxErrorAsEnumResponse());
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return WithErrorSyntaxErrorAsEnumResult.withErr($error.value);
            } else {
              return Future.error($error, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(
                _kWithErrorSyntax_ErrorAsEnum_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types =
                _kWithErrorSyntax_ErrorAsEnum_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kWithErrorSyntax_ErrorAsEnum_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for WithErrorSyntaxBinding');
    }
  }
}

// methodA: (int a, int b)
const int _kChannelProtocol_MethodA_Ordinal = 0x7d92c10fb2d002e;
const $fidl.MethodType _kChannelProtocol_MethodA_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 8),
  ],
  response: [],
  name: r"ChannelProtocol.MethodA",
  requestInlineSize: 16,
  responseInlineSize: 0,
);
// eventA:  -> (int a, int b)
const int _kChannelProtocol_EventA_Ordinal = 0x52c2fa481a687dfa;
const $fidl.MethodType _kChannelProtocol_EventA_Type = $fidl.MethodType(
  request: [],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 8),
  ],
  name: r"ChannelProtocol.EventA",
  requestInlineSize: 0,
  responseInlineSize: 16,
);
// methodB: (int a, int b) -> (int result)
const int _kChannelProtocol_MethodB_Ordinal = 0x5da1d2ed00055cea;
const $fidl.MethodType _kChannelProtocol_MethodB_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 8),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"ChannelProtocol.MethodB",
  requestInlineSize: 16,
  responseInlineSize: 8,
);
// takeHandle: ($zircon.Handle h) -> ()
const int _kChannelProtocol_TakeHandle_Ordinal = 0xc25674355065c28;
const $fidl.MethodType _kChannelProtocol_TakeHandle_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$zircon.Handle>(
        type: $fidl.HandleType(objectType: 0, rights: 2147483648), 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(objectType: 14, rights: 2147483648), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<$zircon.Socket>(
        type: $fidl.SocketType(objectType: 14, rights: 2147483648), 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.IncomingMessage $message) {
    switch ($message.ordinal) {
      case _kChannelProtocol_EventA_Ordinal:
        final String _name = _kChannelProtocol_EventA_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_EventA_Type.response!;
          _eventAEventStreamController.add($fidl
              .decodeMessageWithCallback<ChannelProtocol$EventA$Response>(
                  $message,
                  _kChannelProtocol_EventA_Type.decodeResponseInlineSize(),
                  ($fidl.Decoder decoder) {
            return ChannelProtocol$EventA$Response(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
              $types[1].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          }));
        } 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.IncomingMessage $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    switch ($message.ordinal) {
      case _kChannelProtocol_MethodB_Ordinal:
        final String _name = _kChannelProtocol_MethodB_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kChannelProtocol_MethodB_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kChannelProtocol_MethodB_Type.decodeResponseInlineSize(),
              $types[0]);

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

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

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

  @override
  $async.Future<void> methodA(int a, int b) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kChannelProtocol_MethodA_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodA_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChannelProtocol_MethodA_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize, 1);
      $types[1].encode($encoder, b, $fidl.kMessageHeaderSize, 1);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

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

  @override
  $async.Future<int> methodB(int a, int b) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kChannelProtocol_MethodB_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MethodB_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChannelProtocol_MethodB_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize, 1);
      $types[1].encode($encoder, b, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> takeHandle($zircon.Handle h) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kChannelProtocol_TakeHandle_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_TakeHandle_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChannelProtocol_TakeHandle_Type.encodingRequestInlineSize(),
        () {
      $types[0].encode($encoder, h, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<void>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<$zircon.Socket> mutateSocket($zircon.Socket a) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kChannelProtocol_MutateSocket_Ordinal, 0);
    final List<$fidl.MemberType> $types =
        _kChannelProtocol_MutateSocket_Type.request!;
    $fidl.encodeMessageWithCallback($encoder,
        _kChannelProtocol_MutateSocket_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, a, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<$zircon.Socket>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

    whenBound.then((_) {
      final impl = this.impl;
      if (impl != null) {
        final _eventA_stream = impl.eventA;
        if (_eventA_stream != null) {
          $subscriptions.add(_eventA_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kChannelProtocol_EventA_Ordinal, 0);
            final List<$fidl.MemberType> $types =
                _kChannelProtocol_EventA_Type.response!;
            $fidl.encodeMessageWithCallback($encoder,
                _kChannelProtocol_EventA_Type.encodingResponseInlineSize(), () {
              $types[0]
                  .encode($encoder, $response.a, $fidl.kMessageHeaderSize, 1);
              $types[1]
                  .encode($encoder, $response.b, $fidl.kMessageHeaderSize, 1);
            });
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

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

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

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

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

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

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

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

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

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

  void _handleEvent($fidl.IncomingMessage $message) {
    switch ($message.ordinal) {
      case _kTransitional_Event_Ordinal:
        final String _name = _kTransitional_Event_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTransitional_Event_Type.response!;
          _eventEventStreamController.add($fidl.decodeMessage($message,
              _kTransitional_Event_Type.decodeResponseInlineSize(), $types[0]));
        } catch (_e) {
          ctrl.proxyError(
              $fidl.FidlError('Exception handling event $_name: $_e'));
          ctrl.close();
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.IncomingMessage $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    switch ($message.ordinal) {
      case _kTransitional_Request_Ordinal:
        final String _name = _kTransitional_Request_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kTransitional_Request_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kTransitional_Request_Type.decodeResponseInlineSize(),
              $types[0]);

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

  @override
  $async.Future<int> request(int x) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kTransitional_Request_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kTransitional_Request_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kTransitional_Request_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, x, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

  @override
  $async.Future<void> oneWay(int x) async {
    if (!ctrl.isBound) {
      return $async.Future.error(
          $fidl.FidlStateException('Proxy<${ctrl.$interfaceName}> is closed.'),
          StackTrace.current);
    }

    final $fidl.Encoder $encoder = $fidl.Encoder();
    $encoder.encodeMessageHeader(_kTransitional_OneWay_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kTransitional_OneWay_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kTransitional_OneWay_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, x, $fidl.kMessageHeaderSize, 1);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

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

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

    whenBound.then((_) {
      final impl = this.impl;
      if (impl != null) {
        final _event_stream = impl.event;
        if (_event_stream != null) {
          $subscriptions.add(_event_stream.listen(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kTransitional_Event_Ordinal, 0);
            final List<$fidl.MemberType> $types =
                _kTransitional_Event_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kTransitional_Event_Type.encodingResponseInlineSize(),
                $types[0],
                $response);
            sendMessage($encoder.message);
          }));
        }
      }
    });
    whenClosed.then((_) => $unsubscribe());
  }

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

// method: ()
const int _kDiscoverableProtocol_Method_Ordinal = 0x39790af74e0167;
const $fidl.MethodType _kDiscoverableProtocol_Method_Type = $fidl.MethodType(
  request: [],
  response: [],
  name: r"DiscoverableProtocol.Method",
  requestInlineSize: 0,
  responseInlineSize: 0,
);

abstract class DiscoverableProtocol extends $fidl.Service {
  static const String $serviceName = "fidl.test.protocols.DiscoverableProtocol";
  @override
  $fidl.ServiceData? get $serviceData => DiscoverableProtocolData();
  $async.Future<void> method();
}

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

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

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

class DiscoverableProtocolProxy extends $fidl.AsyncProxy<DiscoverableProtocol>
    implements DiscoverableProtocol {
  DiscoverableProtocolProxy()
      : super($fidl.AsyncProxyController<DiscoverableProtocol>(
            $serviceName: "fidl.test.protocols.DiscoverableProtocol",
            $interfaceName: r'DiscoverableProtocol')) {
    ctrl.onResponse = _handleResponse;
  }
  @override
  $fidl.ServiceData get $serviceData => DiscoverableProtocolData();

  void _handleEvent($fidl.IncomingMessage $message) {
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.IncomingMessage $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final $async.Completer? $completer = ctrl.getCompleter($txid);
    if ($completer == null) {
      $message.closeHandles();
      return;
    }
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

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

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

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kDiscoverableProtocol_Method_Ordinal:
        final String _name = _kDiscoverableProtocol_Method_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types =
              _kDiscoverableProtocol_Method_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>($message,
                  _kDiscoverableProtocol_Method_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.method();
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(
            r'Unexpected message name for DiscoverableProtocolBinding');
    }
  }
}
