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

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

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

// foo: (String s) -> (int y)
const int _kSuper_foo_Ordinal = 0x45602cf3b581d6ab;
const $fidl.MethodType _kSuper_foo_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"Super.foo",
  requestInlineSize: 16,
  responseInlineSize: 8,
);

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

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

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

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

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

  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 _kSuper_foo_Ordinal:
        final String _name = _kSuper_foo_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kSuper_foo_Type.response!;
          $decoder
              .claimMemory(_kSuper_foo_Type.decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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> 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(_kSuper_foo_Ordinal, 0);
    $encoder.alloc(_kSuper_foo_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kSuper_foo_Type.request!;
    $types[0].encode($encoder, s, $fidl.kMessageHeaderSize);
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    switch ($message.ordinal) {
      case _kSuper_foo_Ordinal:
        final String _name = _kSuper_foo_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kSuper_foo_Type.request!;
          $decoder
              .claimMemory(_kSuper_foo_Type.decodeRequestInlineSize($decoder));
          final $async.Future<int> $future = impl!.foo(
            $types[0].decode($decoder, $fidl.kMessageHeaderSize),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kSuper_foo_Ordinal, $message.txid);
            $encoder
                .alloc(_kSuper_foo_Type.encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types = _kSuper_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 SuperBinding');
    }
  }
}

// foo: (String s) -> (int y)
const int _kSub_foo_Ordinal = 0x45602cf3b581d6ab;
const $fidl.MethodType _kSub_foo_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<String>(
        type: $fidl.StringType(maybeElementCount: null), offset: 0),
  ],
  response: <$fidl.MemberType>[
    $fidl.MemberType<int>(type: $fidl.Int64Type(), offset: 0),
  ],
  name: r"Sub.foo",
  requestInlineSize: 16,
  responseInlineSize: 8,
);

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

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

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

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

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

  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 _kSub_foo_Ordinal:
        final String _name = _kSub_foo_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kSub_foo_Type.response!;
          $decoder
              .claimMemory(_kSub_foo_Type.decodeResponseInlineSize($decoder));
          // ignore: prefer_const_declarations
          final $response =
              $types[0].decode($decoder, $fidl.kMessageHeaderSize);

          $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> 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(_kSub_foo_Ordinal, 0);
    $encoder.alloc(_kSub_foo_Type.encodingRequestInlineSize($encoder));
    final List<$fidl.MemberType> $types = _kSub_foo_Type.request!;
    $types[0].encode($encoder, s, $fidl.kMessageHeaderSize);
    final $completer = $async.Completer<int>();
    ctrl.sendMessageWithResponse($encoder.message, $completer);
    return $completer.future;
  }
}

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

  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = $fidl.Decoder($message)
      ..claimMemory($fidl.kMessageHeaderSize);
    switch ($message.ordinal) {
      case _kSub_foo_Ordinal:
        final String _name = _kSub_foo_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kSub_foo_Type.request!;
          $decoder
              .claimMemory(_kSub_foo_Type.decodeRequestInlineSize($decoder));
          final $async.Future<int> $future = impl!.foo(
            $types[0].decode($decoder, $fidl.kMessageHeaderSize),
          );
          $future.then(($response) {
            final $fidl.Encoder $encoder = $fidl.Encoder();
            $encoder.encodeMessageHeader(_kSub_foo_Ordinal, $message.txid);
            $encoder.alloc(_kSub_foo_Type.encodingResponseInlineSize($encoder));
            final List<$fidl.MemberType> $types = _kSub_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 SubBinding');
    }
  }
}
