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

// fidl_experiment = no_optional_structs
// fidl_experiment = output_index_json
// fidl_experiment = simple_empty_response_syntax
// fidl_experiment = unknown_interactions
// fidl_experiment = unknown_interactions_mandate

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
// ignore_for_file: override_on_non_overriding_member

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:
        $message.closeHandles();
        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!;
          final $wireFormat = $message.parseWireFormat();
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kProtocol_RequestStrictResponseFlexible_Type
                  .responseInlineSize($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!;
          final $wireFormat = $message.parseWireFormat();
          // ignore: prefer_const_declarations
          final $response = $fidl.decodeMessage(
              $message,
              _kProtocol_RequestFlexibleResponseStrict_Type
                  .responseInlineSize($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) {
    final $wireFormat = $message.parseWireFormat();
    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($wireFormat),
                  ($fidl.Decoder $decoder, int $offset) {
            return _impl.requestStrictResponseFlexible(
              $types[0].decode($decoder, $offset, 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($wireFormat),
                  ($fidl.Decoder $decoder, int $offset) {
            return _impl.requestFlexibleResponseStrict(
              $types[0].decode($decoder, $offset, 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:
        $message.closeHandles();
        throw $fidl.FidlError(r'Unexpected message name for ProtocolBinding');
    }
  }
}
