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

library fidl_fidl_test_protocols_test;

import 'dart:async' as $async;
import 'dart:core' hide Error, Future, Match, Set, Stream, Type;
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as $fidl;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart' as $zircon;

import './fidl_async.dart';

// ignore_for_file: always_specify_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: one_member_abstracts
// ignore_for_file: public_member_api_docs
// ignore_for_file: unused_import
// ignore_for_file: library_prefixes
// ignore_for_file: unused_shown_name

class WithAndWithoutRequestResponse$TestBase
    extends WithAndWithoutRequestResponse {
  @override
  $async.Future<void> noRequestNoResponse() {
    return $async.Future.error(
        UnimplementedError(
            r'noRequestNoResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> noRequestEmptyResponse() {
    return $async.Future.error(
        UnimplementedError(
            r'noRequestEmptyResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<String> noRequestWithResponse() {
    return $async.Future.error(
        UnimplementedError(
            r'noRequestWithResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> withRequestNoResponse(String arg) {
    return $async.Future.error(
        UnimplementedError(
            r'withRequestNoResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> withRequestEmptyResponse(String arg) {
    return $async.Future.error(
        UnimplementedError(
            r'withRequestEmptyResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<String> withRequestWithResponse(String arg) {
    return $async.Future.error(
        UnimplementedError(
            r'withRequestWithResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Stream<void> get onEmptyResponse {
    return $async.Stream.fromFuture($async.Future.error(
        UnimplementedError(
            r'onEmptyResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current));
  }

  @override
  $async.Stream<String> get onWithResponse {
    return $async.Stream.fromFuture($async.Future.error(
        UnimplementedError(
            r'onWithResponse not implemented on WithAndWithoutRequestResponse test base. Please implement.'),
        StackTrace.current));
  }
}

class WithErrorSyntax$TestBase extends WithErrorSyntax {
  @override
  $async.Future<WithErrorSyntax$ResponseAsStruct$Response> responseAsStruct() {
    return $async.Future.error(
        UnimplementedError(
            r'responseAsStruct not implemented on WithErrorSyntax test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> errorAsPrimitive() {
    return $async.Future.error(
        UnimplementedError(
            r'errorAsPrimitive not implemented on WithErrorSyntax test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> errorAsEnum() {
    return $async.Future.error(
        UnimplementedError(
            r'errorAsEnum not implemented on WithErrorSyntax test base. Please implement.'),
        StackTrace.current);
  }
}

class ChannelProtocol$TestBase extends ChannelProtocol {
  @override
  $async.Future<void> methodA(int a, int b) {
    return $async.Future.error(
        UnimplementedError(
            r'methodA not implemented on ChannelProtocol test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Stream<ChannelProtocol$EventA$Response> get eventA {
    return $async.Stream.fromFuture($async.Future.error(
        UnimplementedError(
            r'eventA not implemented on ChannelProtocol test base. Please implement.'),
        StackTrace.current));
  }

  @override
  $async.Future<int> methodB(int a, int b) {
    return $async.Future.error(
        UnimplementedError(
            r'methodB not implemented on ChannelProtocol test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> takeHandle($zircon.Handle h) {
    return $async.Future.error(
        UnimplementedError(
            r'takeHandle not implemented on ChannelProtocol test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<$zircon.Socket> mutateSocket($zircon.Socket a) {
    return $async.Future.error(
        UnimplementedError(
            r'mutateSocket not implemented on ChannelProtocol test base. Please implement.'),
        StackTrace.current);
  }
}

class Transitional$TestBase extends Transitional {
  @override
  $async.Future<int> request(int x) {
    return $async.Future.error(
        UnimplementedError(
            r'request not implemented on Transitional test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Future<void> oneWay(int x) {
    return $async.Future.error(
        UnimplementedError(
            r'oneWay not implemented on Transitional test base. Please implement.'),
        StackTrace.current);
  }

  @override
  $async.Stream<int> get event {
    return $async.Stream.fromFuture($async.Future.error(
        UnimplementedError(
            r'event not implemented on Transitional test base. Please implement.'),
        StackTrace.current));
  }
}

class DiscoverableProtocol$TestBase extends DiscoverableProtocol {
  @override
  $async.Future<void> method() {
    return $async.Future.error(
        UnimplementedError(
            r'method not implemented on DiscoverableProtocol test base. Please implement.'),
        StackTrace.current);
  }
}
