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

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

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

  @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.XUnionType<ExampleFooResult> kExample_foo_Result_Type =
    $fidl.XUnionType<ExampleFooResult>(
  members: <int, $fidl.FidlType>{
    1: kExample_foo_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: ExampleFooResult._ctor,
  nullable: false,
  flexible: false,
);
// See fxbug.dev/7644:
// ignore: recursive_compile_time_constant
const $fidl.XUnionType<ExampleFooResult> kExample_foo_Result_OptType =
    $fidl.XUnionType<ExampleFooResult>(
  members: <int, $fidl.FidlType>{
    1: kExample_foo_Response_Type,
    2: $fidl.Uint32Type(),
  },
  ctor: ExampleFooResult._ctor,
  nullable: true,
  flexible: 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, nullable: false),
        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 extends $fidl.Service {
  static const String $serviceName = null;
  @override
  $fidl.ServiceData get $serviceData => ExampleData();
  $async.Future<int> foo(String s);
}

class ExampleData implements $fidl.ServiceData<Example> {
  const ExampleData();

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

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

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

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

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    switch ($message.ordinal) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

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

          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);
    $encoder.alloc(_kExample_foo_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kExample_foo_Type.request;
    $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) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    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;
          $decoder.claimMemory(
              _kExample_foo_Type.decodeRequestInlineSize($decoder));
          final $async.Future<int> $future = 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);
            $encoder
                .alloc(_kExample_foo_Type.encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types = _kExample_foo_Type.response;
            $types[0].encode($encoder, $response, $fidl.kMessageHeaderSize);
            $respond($encoder.message);
          }, onError: (_e) {
            close();
            print('Exception handling method call $_name: $_e');
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for ExampleBinding');
    }
  }
}
