blob: f8807d2dd93b52f43b03dd9053632c386538d95f [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
import 'package:analysis_server/protocol/protocol.dart';
/// Instances of the class [ChannelChunkSink] uses a [Converter] to translate
/// chunks.
class ChannelChunkSink<S, T> extends ChunkedConversionSink<S> {
/// The converter used to translate chunks.
final Converter<S, T> converter;
/// The sink to which the converted chunks are added.
final Sink sink;
/// A flag indicating whether the sink has been closed.
bool closed = false;
/// Initialize a newly create sink to use the given [converter] to convert
/// chunks before adding them to the given [sink].
ChannelChunkSink(this.converter, this.sink);
void add(S chunk) {
if (!closed) {
var convertedChunk = converter.convert(chunk);
if (convertedChunk != null) {
void close() {
closed = true;
/// The abstract class [ClientCommunicationChannel] defines the behavior of
/// objects that allow a client to send [Request]s to an [AnalysisServer] and to
/// receive both [Response]s and [Notification]s.
abstract class ClientCommunicationChannel {
/// The stream of notifications from the server.
Stream<Notification> notificationStream;
/// The stream of responses from the server.
Stream<Response> responseStream;
/// Close the channel to the server. Once called, all future communication
/// with the server via [sendRequest] will silently be ignored.
Future close();
/// Send the given [request] to the server
/// and return a future with the associated [Response].
Future<Response> sendRequest(Request request);
/// Instances of the class [JsonStreamDecoder] convert JSON strings to JSON
/// maps.
class JsonStreamDecoder extends Converter<String, Map> {
Map convert(String text) => json.decode(text);
ChunkedConversionSink<String> startChunkedConversion(Sink<Map> sink) =>
ChannelChunkSink<String, Map>(this, sink);
/// Instances of the class [NotificationConverter] convert JSON maps to
/// [Notification]s.
class NotificationConverter extends Converter<Map, Notification> {
Notification convert(Map json) => Notification.fromJson(json);
ChunkedConversionSink<Map> startChunkedConversion(Sink<Notification> sink) =>
ChannelChunkSink<Map, Notification>(this, sink);
/// Instances of the class [ResponseConverter] convert JSON maps to [Response]s.
class ResponseConverter extends Converter<Map, Response> {
Response convert(Map json) => Response.fromJson(json);
ChunkedConversionSink<Map> startChunkedConversion(Sink<Response> sink) =>
ChannelChunkSink<Map, Response>(this, sink);
/// The abstract class [ServerCommunicationChannel] defines the behavior of
/// objects that allow an [AnalysisServer] to receive [Request]s and to return
/// both [Response]s and [Notification]s.
abstract class ServerCommunicationChannel {
/// Close the communication channel.
void close();
/// Listen to the channel for requests. If a request is received, invoke the
/// [onRequest] function. If an error is encountered while trying to read from
/// the socket, invoke the [onError] function. If the socket is closed by the
/// client, invoke the [onDone] function.
/// Only one listener is allowed per channel.
void listen(void Function(Request request) onRequest,
{Function onError, void Function() onDone});
/// Send the given [notification] to the client.
void sendNotification(Notification notification);
/// Send the given [response] to the client.
void sendResponse(Response response);