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

library fidl_fidl_test_inheritancewithrecursivedecl_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();

// first: ($fidl.InterfaceRequest<Parent> request)
const int _kParent_First_Ordinal = 0x2a592d0a81dac39b;
const $fidl.MethodType _kParent_First_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$fidl.InterfaceRequest<Parent>>(
        type: $fidl.InterfaceRequestType<Parent>(), offset: 0),
  ],
  response: [],
  name: r"Parent.First",
  requestInlineSize: 8,
  responseInlineSize: 0,
);

abstract class Parent {
  $fidl.ServiceData? get $serviceData => ParentData();
  $async.Future<void> first($fidl.InterfaceRequest<Parent> request);
}

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

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

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

class ParentProxy extends $fidl.AsyncProxy<Parent> implements Parent {
  ParentProxy()
      : super($fidl.AsyncProxyController<Parent>($interfaceName: r'Parent')) {
    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}'));
        ctrl.close();
        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) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<void> first($fidl.InterfaceRequest<Parent> request) 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(_kParent_First_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kParent_First_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kParent_First_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, request, $fidl.kMessageHeaderSize, 1);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }
}

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

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kParent_First_Ordinal:
        final String _name = _kParent_First_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kParent_First_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message, _kParent_First_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.first(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for ParentBinding');
    }
  }
}

// first: ($fidl.InterfaceRequest<Parent> request)
const int _kChild_First_Ordinal = 0x2a592d0a81dac39b;
const $fidl.MethodType _kChild_First_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$fidl.InterfaceRequest<Parent>>(
        type: $fidl.InterfaceRequestType<Parent>(), offset: 0),
  ],
  response: [],
  name: r"Child.First",
  requestInlineSize: 8,
  responseInlineSize: 0,
);
// second: ($fidl.InterfaceRequest<Parent> request)
const int _kChild_Second_Ordinal = 0x6cba5c5e01fee86;
const $fidl.MethodType _kChild_Second_Type = $fidl.MethodType(
  request: <$fidl.MemberType>[
    $fidl.MemberType<$fidl.InterfaceRequest<Parent>>(
        type: $fidl.InterfaceRequestType<Parent>(), offset: 0),
  ],
  response: [],
  name: r"Child.Second",
  requestInlineSize: 8,
  responseInlineSize: 0,
);

abstract class Child {
  $fidl.ServiceData? get $serviceData => ChildData();
  $async.Future<void> first($fidl.InterfaceRequest<Parent> request);
  $async.Future<void> second($fidl.InterfaceRequest<Parent> request);
}

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

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

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

class ChildProxy extends $fidl.AsyncProxy<Child> implements Child {
  ChildProxy()
      : super($fidl.AsyncProxyController<Child>($interfaceName: r'Child')) {
    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}'));
        ctrl.close();
        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) {
      default:
        ctrl.proxyError(
            $fidl.FidlError('Unexpected message ordinal: ${$message.ordinal}'));
        ctrl.close();
        break;
    }
  }

  @override
  $async.Future<void> first($fidl.InterfaceRequest<Parent> request) 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(_kChild_First_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kChild_First_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChild_First_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, request, $fidl.kMessageHeaderSize, 1);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }

  @override
  $async.Future<void> second($fidl.InterfaceRequest<Parent> request) 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(_kChild_Second_Ordinal, 0);
    final List<$fidl.MemberType> $types = _kChild_Second_Type.request!;
    $fidl.encodeMessageWithCallback(
        $encoder, _kChild_Second_Type.encodingRequestInlineSize(), () {
      $types[0].encode($encoder, request, $fidl.kMessageHeaderSize, 1);
    });
    return $async.Future.sync(() {
      ctrl.sendMessage($encoder.message);
    });
  }
}

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

  @override
  void handleMessage(
      $fidl.IncomingMessage $message, $fidl.OutgoingMessageSink $respond) {
    switch ($message.ordinal) {
      case _kChild_First_Ordinal:
        final String _name = _kChild_First_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kChild_First_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message, _kChild_First_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.first(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      case _kChild_Second_Ordinal:
        final String _name = _kChild_Second_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kChild_Second_Type.request!;
          // ignore: prefer_const_declarations
          final _impl = impl!;
          final $async.Future<void> $future = $fidl
              .decodeMessageWithCallback<$async.Future<void>>(
                  $message, _kChild_Second_Type.decodeRequestInlineSize(),
                  ($fidl.Decoder decoder) {
            return _impl.second(
              $types[0].decode(decoder, $fidl.kMessageHeaderSize, 1),
            );
          });
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for ChildBinding');
    }
  }
}
