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

library fidl_fidl_test_error_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

enum ExampleFooResultTag {
  response, // 0x1
  err, // 0x2
}

const Map<int, ExampleFooResultTag> _ExampleFooResultTag_map = {
  1: ExampleFooResultTag.response,
  2: ExampleFooResultTag.err,
};

class ExampleFooResult extends $fidl.XUnion {
  const ExampleFooResult.withResponse(ExampleFooResponse value)
      : _ordinal = 1,
        _data = value;

  const ExampleFooResult.withErr(int value)
      : _ordinal = 2,
        _data = value;

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

  final int _ordinal;
  final _data;

  ExampleFooResultTag get $tag => _ExampleFooResultTag_map[_ordinal]!;

  ExampleFooResponse? 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'ExampleFooResult.response(' + response.toString() + ')';
      case 2:
        return r'ExampleFooResult.err(' + err.toString() + ')';
      default:
        return r'ExampleFooResult.<UNKNOWN>';
    }
  }

  @override
  int get $ordinal => _ordinal;

  @override
  Object get $data => _data;

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<ExampleFooResult> kExample_foo_Result_Type =
    $fidl.UnionType<ExampleFooResult>(
  members: <int, $fidl.FidlType>{
    1: kExample_foo_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: ExampleFooResult._ctor,
  flexible: false,
  resource: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.NullableUnionType<ExampleFooResult> kExample_foo_Result_OptType =
    $fidl.NullableUnionType<ExampleFooResult>(
  members: <int, $fidl.FidlType>{
    1: kExample_foo_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: ExampleFooResult._ctor,
  flexible: false,
  resource: false,
);

class ExampleFooResponse extends $fidl.Struct {
  const ExampleFooResponse({
    required this.y,
  });
  ExampleFooResponse.clone(
    ExampleFooResponse $orig, {
    int? y,
  }) : this(
          y: y ?? $orig.y,
        );

  final int y;

  @override
  List<Object?> get $fields {
    return <Object?>[
      y,
    ];
  }

  static const $fieldType0 = $fidl.Int64Type();

  @override
  void $encode($fidl.Encoder $encoder, int $offset) {
    $fieldType0.encode($encoder, y, $offset + 0);
  }

  @override
  String toString() {
    return r'ExampleFooResponse' r'(y: ' + y.toString() + r')';
  }

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

// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.StructType<ExampleFooResponse> kExample_foo_Response_Type =
    $fidl.StructType<ExampleFooResponse>(
  inlineSize: 8,
  structDecode: ExampleFooResponse._structDecode,
);

// ignore: unused_element, avoid_private_typedef_functions
typedef _VoidCallback = void Function();

// foo: (String s) -> (int y)
const int _kExample_foo_Ordinal = 0x57e41804562237ae;
const $fidl.MethodType _kExample_foo_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<ExampleFooResult>(
        type: kExample_foo_Result_Type, offset: 0),
  ],
  name: r"Example.foo",
  requestInlineSize: 16,
  responseInlineSize: 24,
);

abstract class Example {
  $fidl.ServiceData? get $serviceData => ExampleData();
  $async.Future<int> foo(String s);
}

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

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

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

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

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

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

          if ($response.$tag == ExampleFooResultTag.response) {
            $completer.complete($response.response.y);
          } 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<int> foo(String s) 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(_kExample_foo_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kExample_foo_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kExample_foo_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, s, $fidl.kMessageHeaderSize);
    });
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    switch ($message.ordinal) {
      case _kExample_foo_Ordinal:
        final String _name = _kExample_foo_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kExample_foo_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<int> $future = $fidl
              .decodeMessageWithCallback<$async.Future<int>>(
                  $message, _kExample_foo_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.foo(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize),
            );
          });
          $future.then(($responseValue) {
            return ExampleFooResult.withResponse(
                ExampleFooResponse(y: $responseValue));
          }, onError: ($error) {
            if ($error is $fidl.MethodException) {
              return ExampleFooResult.withErr($error.value);
            } else {
              return Future.error($error, StackTrace.current);
            }
          }).then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kExample_foo_Ordinal, $message.txid);
            final List<$fidl.MemberType> $types = _kExample_foo_Type.response!;
            $fidl.encodeMessage(
                $encoder,
                _kExample_foo_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 ExampleBinding');
    }
  }
}
