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

// 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:
        $fidl.handleCtrlError(
            ctrl, '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) {
      default:
        $fidl.handleCtrlError(
            ctrl, 'Unexpected message ordinal: ${$message.ordinal}');
        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;
        $fidl.performWithExceptionHandling(_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),
            );
          });
        }, close);
        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:
        $fidl.handleCtrlError(
            ctrl, '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) {
      default:
        $fidl.handleCtrlError(
            ctrl, 'Unexpected message ordinal: ${$message.ordinal}');
        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;
        $fidl.performWithExceptionHandling(_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),
            );
          });
        }, close);
        break;
      case _kChild_Second_Ordinal:
        final String _name = _kChild_Second_Type.name;
        $fidl.performWithExceptionHandling(_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),
            );
          });
        }, close);
        break;
      default:
        throw $fidl.FidlError(r'Unexpected message name for ChildBinding');
    }
  }
}
