// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WARNING: This file is machine generated by fidlgen.

library fidl_test_name_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 $zx;

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

  @override
  $async.Future<void> noRequestEmptyResponse() {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Future<String> noRequestWithResponse() {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Future<void> withRequestNoResponse(String arg) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Future<void> withRequestEmptyResponse(String arg) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Future<String> withRequestWithResponse(String arg) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Stream<void> get onEmptyResponse {
    return $async.Stream.fromFuture($async.Future.error(UnimplementedError()));
  }

  @override
  $async.Stream<String> get onWithResponse {
    return $async.Stream.fromFuture($async.Future.error(UnimplementedError()));
  }
}

class WithErrorSyntax$TestBase extends WithErrorSyntax {
  @override
  $async.Future<void> errorAsPrimitive() {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Future<void> errorAsEnum() {
    return $async.Future.error(UnimplementedError());
  }
}

class OvernetInternalProtocol$TestBase extends OvernetInternalProtocol {
  @override
  $async.Future<void> methodA(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Stream<OvernetInternalProtocol$EventA$Response> get eventA {
    return $async.Stream.fromFuture($async.Future.error(UnimplementedError()));
  }

  @override
  $async.Future<int> methodB(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }
}

class SocketControlProtocol$TestBase extends SocketControlProtocol {
  @override
  $async.Future<void> methodA(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Stream<SocketControlProtocol$EventA$Response> get eventA {
    return $async.Stream.fromFuture($async.Future.error(UnimplementedError()));
  }

  @override
  $async.Future<int> methodB(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }
}

class ChannelProtocol$TestBase extends ChannelProtocol {
  @override
  $async.Future<void> methodA(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Stream<ChannelProtocol$EventA$Response> get eventA {
    return $async.Stream.fromFuture($async.Future.error(UnimplementedError()));
  }

  @override
  $async.Future<int> methodB(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }
}

class KitchenSink$TestBase extends KitchenSink {
  @override
  $async.Future<void> methodA(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }

  @override
  $async.Stream<KitchenSink$EventA$Response> get eventA {
    return $async.Stream.fromFuture($async.Future.error(UnimplementedError()));
  }

  @override
  $async.Future<int> methodB(int a, int b) {
    return $async.Future.error(UnimplementedError());
  }
}
