1// Copyright 2018 The Go Authors. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package protocol 16 17import ( 18 "context" 19 "encoding/json" 20 "log" 21 22 "../jsonrpc2" 23) 24 25const ( 26 // RequestCancelledError should be used when a request is cancelled early. 27 RequestCancelledError = -32800 28) 29 30type DocumentUri = string 31 32type canceller struct{ jsonrpc2.EmptyHandler } 33 34type clientHandler struct { 35 canceller 36 client Client 37} 38 39type serverHandler struct { 40 canceller 41 server Server 42} 43 44func (canceller) Request(ctx context.Context, conn *jsonrpc2.Conn, direction jsonrpc2.Direction, r *jsonrpc2.WireRequest) context.Context { 45 if direction == jsonrpc2.Receive && r.Method == "$/cancelRequest" { 46 var params CancelParams 47 if err := json.Unmarshal(*r.Params, ¶ms); err != nil { 48 log.Printf("%v", err) 49 } else { 50 conn.Cancel(params.ID) 51 } 52 } 53 return ctx 54} 55 56func (canceller) Cancel(ctx context.Context, conn *jsonrpc2.Conn, id jsonrpc2.ID, cancelled bool) bool { 57 if cancelled { 58 return false 59 } 60 conn.Notify(ctx, "$/cancelRequest", &CancelParams{ID: id}) 61 return true 62} 63 64func NewClient(ctx context.Context, stream jsonrpc2.Stream, client Client) (context.Context, *jsonrpc2.Conn, Server) { 65 ctx = WithClient(ctx, client) 66 conn := jsonrpc2.NewConn(stream) 67 conn.AddHandler(&clientHandler{client: client}) 68 return ctx, conn, &serverDispatcher{Conn: conn} 69} 70 71func NewServer(ctx context.Context, stream jsonrpc2.Stream, server Server) (context.Context, *jsonrpc2.Conn, Client) { 72 conn := jsonrpc2.NewConn(stream) 73 client := &clientDispatcher{Conn: conn} 74 ctx = WithClient(ctx, client) 75 conn.AddHandler(&serverHandler{server: server}) 76 return ctx, conn, client 77} 78 79func sendParseError(ctx context.Context, req *jsonrpc2.Request, err error) { 80 if _, ok := err.(*jsonrpc2.Error); !ok { 81 err = jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err) 82 } 83 if err := req.Reply(ctx, nil, err); err != nil { 84 log.Printf("%v", err) 85 } 86} 87