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

library fidl_test_requestflexibleenvelope_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: directives_ordering
// 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

enum FlexibleFooTag {
  $unknown,
  s, // 0x1
  i, // 0x2
}

const Map<int, FlexibleFooTag> _FlexibleFooTag_map = {
  1: FlexibleFooTag.s,
  2: FlexibleFooTag.i,
};

class FlexibleFoo extends $fidl.Union {
  const FlexibleFoo.withS(String value)
      : _ordinal = 1,
        _data = value;

  const FlexibleFoo.withI(int value)
      : _ordinal = 2,
        _data = value;
  const FlexibleFoo.with$UnknownData(this._ordinal, $fidl.UnknownRawData data)
      : _data = data;

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

  final int _ordinal;
  final _data;

  FlexibleFooTag get $tag =>
      _FlexibleFooTag_map[_ordinal] ?? FlexibleFooTag.$unknown;

  String? get s {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

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

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

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<FlexibleFoo> kFlexibleFoo_Type =
    $fidl.UnionType<FlexibleFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: FlexibleFoo._ctor,
  flexible: true,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<FlexibleFoo> kFlexibleFoo_OptType =
    $fidl.NullableUnionType<FlexibleFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: FlexibleFoo._ctor,
  flexible: true,
  resource: false,
);

enum StrictFooTag {
  s, // 0x1
  i, // 0x2
}

const Map<int, StrictFooTag> _StrictFooTag_map = {
  1: StrictFooTag.s,
  2: StrictFooTag.i,
};

class StrictFoo extends $fidl.Union {
  const StrictFoo.withS(String value)
      : _ordinal = 1,
        _data = value;

  const StrictFoo.withI(int value)
      : _ordinal = 2,
        _data = value;

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

  final int _ordinal;
  final _data;

  StrictFooTag get $tag => _StrictFooTag_map[_ordinal]!;

  String? get s {
    if (_ordinal != 1) {
      return null;
    }
    return _data;
  }

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

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

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<StrictFoo> kStrictFoo_Type = $fidl.UnionType<StrictFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: StrictFoo._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<StrictFoo> kStrictFoo_OptType =
    $fidl.NullableUnionType<StrictFoo>(
  members: <int, $fidl.FidlType>{
    1: $fidl.StringType(maybeElementCount: null),
    2: $fidl.Int32Type(),
  },
  ctor: StrictFoo._ctor,
  flexible: false,
  resource: false,
);

// requestStrictResponseFlexible: (StrictFoo s) -> (FlexibleFoo f)
const int _kProtocol_RequestStrictResponseFlexible_Ordinal = 0x9b8c7d3d118df13;
const $fidl.MethodType _kProtocol_RequestStrictResponseFlexible_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<StrictFoo>(type: kStrictFoo_Type, offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<FlexibleFoo>(type: kFlexibleFoo_Type, offset: 0),
  ],
  name: r"Protocol.RequestStrictResponseFlexible",
  requestInlineSizeV2: 16,
  responseInlineSizeV2: 16,
);
// requestFlexibleResponseStrict: (FlexibleFoo s) -> (StrictFoo f)
const int _kProtocol_RequestFlexibleResponseStrict_Ordinal = 0x480c77690533acb7;
const $fidl.MethodType _kProtocol_RequestFlexibleResponseStrict_Type =
    $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<FlexibleFoo>(type: kFlexibleFoo_Type, offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<StrictFoo>(type: kStrictFoo_Type, offset: 0),
  ],
  name: r"Protocol.RequestFlexibleResponseStrict",
  requestInlineSizeV2: 16,
  responseInlineSizeV2: 16,
);

abstract class Protocol {
  $fidl.ServiceData? get $serviceData => ProtocolData();
  $async.Future<FlexibleFoo> requestStrictResponseFlexible(StrictFoo s);
  $async.Future<StrictFoo> requestFlexibleResponseStrict(FlexibleFoo s);
} // TODO: Remove ServiceData for non-service

class ProtocolData implements $fidl.ServiceData<Protocol> {
  const ProtocolData();

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

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

class ProtocolProxy extends $fidl.AsyncProxy<Protocol> implements Protocol {
  ProtocolProxy()
      : super(
            $fidl.AsyncProxyController<Protocol>($interfaceName: r'Protocol')) {
    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}'));
        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 _kProtocol_RequestStrictResponseFlexible_Ordinal:
        final String _name = _kProtocol_RequestStrictResponseFlexible_Type.name;
        $fidl.performCtrlWithExceptionHandling(
            _name, ctrl, 'method response', $completer.completeError, () {
          final List<$fidl.MemberType> $types =
              _kProtocol_RequestStrictResponseFlexible_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kProtocol_RequestStrictResponseFlexible_Type
                  .responseInlineSize($message.wireFormat),
              $types[0]);

          $completer.complete($response);
        });
        break;
      case _kProtocol_RequestFlexibleResponseStrict_Ordinal:
        final String _name = _kProtocol_RequestFlexibleResponseStrict_Type.name;
        $fidl.performCtrlWithExceptionHandling(
            _name, ctrl, 'method response', $completer.completeError, () {
          final List<$fidl.MemberType> $types =
              _kProtocol_RequestFlexibleResponseStrict_Type.response!;
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kProtocol_RequestFlexibleResponseStrict_Type
                  .responseInlineSize($message.wireFormat),
              $types[0]);

          $completer.complete($response);
        });
        break;
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        break;
    }
  }

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

    final $fidl.Encoder $encoder = $fidl.Encoder($fidl.kWireFormatDefault);
    $encoder.encodeMessageHeader(
        _kProtocol_RequestStrictResponseFlexible_Ordinal,
        0,
        $fidl.CallStrictness.strict);
    final List<$fidl.MemberType> $types =
        _kProtocol_RequestStrictResponseFlexible_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kProtocol_RequestStrictResponseFlexible_Type
            .requestInlineSize($encoder.wireFormat), () {
      $types[0].encode($encoder, s, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<FlexibleFoo>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }

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

    final $fidl.Encoder $encoder = $fidl.Encoder($fidl.kWireFormatDefault);
    $encoder.encodeMessageHeader(
        _kProtocol_RequestFlexibleResponseStrict_Ordinal,
        0,
        $fidl.CallStrictness.strict);
    final List<$fidl.MemberType> $types =
        _kProtocol_RequestFlexibleResponseStrict_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder,
        _kProtocol_RequestFlexibleResponseStrict_Type
            .requestInlineSize($encoder.wireFormat), () {
      $types[0].encode($encoder, s, $fidl.kMessageHeaderSize, 1);
    });
    final $completer = $async.Completer<StrictFoo>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kProtocol_RequestStrictResponseFlexible_Ordinal:
        final String _name = _kProtocol_RequestStrictResponseFlexible_Type.name;
        $fidl.performWithExceptionHandling(_name, () {
          final List<$fidl.MemberType> $types =
              _kProtocol_RequestStrictResponseFlexible_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<FlexibleFoo> $future = $fidl
              .decodeMessageWithCallback<$async.Future<FlexibleFoo>>(
                  $message,
                  _kProtocol_RequestStrictResponseFlexible_Type
                      .requestInlineSize($message.wireFormat),
                  ($fidl.Decoder decoder) {
            return _impl.requestStrictResponseFlexible(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder =
                $fidl.Encoder($fidl.kWireFormatDefault);
            $encoder.encodeMessageHeader(
                _kProtocol_RequestStrictResponseFlexible_Ordinal,
                $message.txid,
                $fidl.CallStrictness.strict);
            final List<$fidl.MemberType> $types =
                _kProtocol_RequestStrictResponseFlexible_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kProtocol_RequestStrictResponseFlexible_Type
                    .responseInlineSize($encoder.wireFormat),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            $fidl.handleException(_name, _e, close);
          });
        }, close);
        break;
      case _kProtocol_RequestFlexibleResponseStrict_Ordinal:
        final String _name = _kProtocol_RequestFlexibleResponseStrict_Type.name;
        $fidl.performWithExceptionHandling(_name, () {
          final List<$fidl.MemberType> $types =
              _kProtocol_RequestFlexibleResponseStrict_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<StrictFoo> $future = $fidl
              .decodeMessageWithCallback<$async.Future<StrictFoo>>(
                  $message,
                  _kProtocol_RequestFlexibleResponseStrict_Type
                      .requestInlineSize($message.wireFormat),
                  ($fidl.Decoder decoder) {
            return _impl.requestFlexibleResponseStrict(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
          $future.then(($response) {
            final $fidl.Encoder $encoder =
                $fidl.Encoder($fidl.kWireFormatDefault);
            $encoder.encodeMessageHeader(
                _kProtocol_RequestFlexibleResponseStrict_Ordinal,
                $message.txid,
                $fidl.CallStrictness.strict);
            final List<$fidl.MemberType> $types =
                _kProtocol_RequestFlexibleResponseStrict_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kProtocol_RequestFlexibleResponseStrict_Type
                    .responseInlineSize($encoder.wireFormat),
                $types[0],
                $response);
            $respond($encoder.message);
          }, onError: (_e) {
            $fidl.handleException(_name, _e, close);
          });
        }, close);
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for ProtocolBinding');
    }
  }
}
