1
0
mirror of https://github.com/golang/go synced 2024-11-19 00:54:42 -07:00
go/internal/lsp/protocol/protocol.go
Ian Cottrell 7b212d60a1 internal/event: renaming the main event API functions
event.Log removed
event.Print -> event.Log
event.Record -> event.Metric
event.StartSpan -> event.Start

In order to support this core now exposes the MakeEvent and Export functions.

Change-Id: Ic7550d88dbf400e32c419adbb61d1546c471841e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/229238
Reviewed-by: Robert Findley <rfindley@google.com>
2020-04-23 17:21:36 +00:00

81 lines
2.4 KiB
Go

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package protocol
import (
"context"
"encoding/json"
"fmt"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/jsonrpc2"
"golang.org/x/tools/internal/xcontext"
)
var (
// RequestCancelledError should be used when a request is cancelled early.
RequestCancelledError = jsonrpc2.NewError(-32800, "JSON RPC cancelled")
)
// ClientDispatcher returns a Client that dispatches LSP requests across the
// given jsonrpc2 connection.
func ClientDispatcher(conn *jsonrpc2.Conn) Client {
return &clientDispatcher{Conn: conn}
}
// ServerDispatcher returns a Server that dispatches LSP requests across the
// given jsonrpc2 connection.
func ServerDispatcher(conn *jsonrpc2.Conn) Server {
return &serverDispatcher{Conn: conn}
}
func Handlers(handler jsonrpc2.Handler) jsonrpc2.Handler {
return CancelHandler(
CancelHandler(
jsonrpc2.AsyncHandler(
jsonrpc2.MustReplyHandler(handler))))
}
func CancelHandler(handler jsonrpc2.Handler) jsonrpc2.Handler {
handler, canceller := jsonrpc2.CancelHandler(handler)
return func(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2.Request) error {
if req.Method() != "$/cancelRequest" {
return handler(ctx, reply, req)
}
var params CancelParams
if err := json.Unmarshal(req.Params(), &params); err != nil {
return sendParseError(ctx, reply, err)
}
if n, ok := params.ID.(float64); ok {
canceller(jsonrpc2.NewIntID(int64(n)))
} else if s, ok := params.ID.(string); ok {
canceller(jsonrpc2.NewStringID(s))
} else {
return sendParseError(ctx, reply, fmt.Errorf("request ID %v malformed", params.ID))
}
return reply(ctx, nil, nil)
}
}
func Call(ctx context.Context, conn *jsonrpc2.Conn, method string, params interface{}, result interface{}) error {
id, err := conn.Call(ctx, method, params, result)
if ctx.Err() != nil {
cancelCall(ctx, conn, id)
}
return err
}
func cancelCall(ctx context.Context, conn *jsonrpc2.Conn, id jsonrpc2.ID) {
ctx = xcontext.Detach(ctx)
ctx, done := event.Start(ctx, "protocol.canceller")
defer done()
// Note that only *jsonrpc2.ID implements json.Marshaler.
conn.Notify(ctx, "$/cancelRequest", &CancelParams{ID: &id})
}
func sendParseError(ctx context.Context, reply jsonrpc2.Replier, err error) error {
return reply(ctx, nil, fmt.Errorf("%w: %s", jsonrpc2.ErrParse, err))
}