From ca8a290ca5733015fd8f7b87caca2cc7490afdb7 Mon Sep 17 00:00:00 2001 From: Ian Cottrell Date: Thu, 16 Apr 2020 20:49:59 -0400 Subject: [PATCH] gopls: convert replay to use the new message types this save it from having to understand the json wire format. Change-Id: I4261cb53a4d5fe2263d7d73ebf9e96e6be2e54a1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/228720 Run-TryBot: Ian Cottrell Reviewed-by: Peter Weinberger --- gopls/integration/replay/main.go | 125 +++++++------------------------ 1 file changed, 29 insertions(+), 96 deletions(-) diff --git a/gopls/integration/replay/main.go b/gopls/integration/replay/main.go index 0090eebdab..0a1ff6b8a6 100644 --- a/gopls/integration/replay/main.go +++ b/gopls/integration/replay/main.go @@ -35,29 +35,6 @@ var ( svresp = make(map[string]*parse.Logmsg) ) -type wireRequest struct { - VersionTag string `json:"jsonrpc"` - Method string `json:"method"` - Params *json.RawMessage `json:"params,omitempty"` - ID *jsonrpc2.ID `json:"id,omitempty"` -} - -type wireResponse struct { - VersionTag string `json:"jsonrpc"` - Result *json.RawMessage `json:"result,omitempty"` - Error interface{} `json:"error,omitempty"` - ID *jsonrpc2.ID `json:"id,omitempty"` -} - -type wireCombined struct { - VersionTag interface{} `json:"jsonrpc"` - ID *jsonrpc2.ID `json:"id,omitempty"` - Method string `json:"method"` - Params *json.RawMessage `json:"params,omitempty"` - Result *json.RawMessage `json:"result,omitempty"` - Error interface{} `json:"error,omitempty"` -} - func main() { log.SetFlags(log.Lshortfile) flag.Usage = func() { @@ -162,42 +139,7 @@ func main() { } } -func msgType(c *wireCombined) parse.MsgType { - // Method, Params, ID => request - // Method, Params, no-ID => notification - // Error => error response - // Result, ID => response - if c.Error != nil { - return parse.ReportErr - } - if c.Params != nil && c.ID != nil { - // $/cancel could be either, cope someday - if parse.FromServer(c.Method) { - return parse.SvRequest - } - return parse.ClRequest - } - if c.Params != nil { - // we're receiving it, so it must be ToClient - return parse.ToClient - } - if c.Result == nil { - if c.ID != nil { - return parse.ClResponse - } - log.Printf("%+v", *c) - panic("couldn't determine direction") - } - // we've received it, so it must be ClResponse - return parse.ClResponse -} - func send(ctx context.Context, l *parse.Logmsg, stream jsonrpc2.Stream, id *jsonrpc2.ID) { - x, err := json.Marshal(l.Body) - if err != nil { - log.Fatal(err) - } - y := json.RawMessage(x) if id == nil { // need to use the number version of ID n, err := strconv.Atoi(l.ID) @@ -206,50 +148,42 @@ func send(ctx context.Context, l *parse.Logmsg, stream jsonrpc2.Stream, id *json } id = jsonrpc2.NewIntID(int64(n)) } - var r interface{} + var msg interface{} + var err error switch l.Type { case parse.ClRequest: - r = wireRequest{ - VersionTag: "2.0", - ID: id, - Method: l.Method, - Params: &y, - } + msg, err = jsonrpc2.NewCall(*id, l.Method, l.Body) case parse.SvResponse: - r = wireResponse{ - VersionTag: "2.0", - ID: id, - Result: &y, - } + msg, err = jsonrpc2.NewResponse(*id, l.Body, nil) case parse.ToServer: - r = wireRequest{ - VersionTag: "2.0", - Method: l.Method, - Params: &y, - } + msg, err = jsonrpc2.NewNotification(l.Method, l.Body) default: log.Fatalf("sending %s", l.Type) } - data, err := json.Marshal(r) + if err != nil { + log.Fatal(err) + } + data, err := json.Marshal(msg) if err != nil { log.Fatal(err) } stream.Write(ctx, data) } -func respond(ctx context.Context, c *wireCombined, stream jsonrpc2.Stream) { +func respond(ctx context.Context, c *jsonrpc2.Call, stream jsonrpc2.Stream) { // c is a server request // pick out the id, and look for the response in msgs - id := fmt.Sprint(c.ID) + id := c.ID() + idstr := fmt.Sprint(id) for _, l := range msgs { - if l.ID == id && l.Type == parse.SvResponse { + if l.ID == idstr && l.Type == parse.SvResponse { // check that the methods match? // need to send back the same ID we got. - send(ctx, l, stream, c.ID) + send(ctx, l, stream, &id) return } } - log.Fatalf("no response found %q %+v %+v", c.Method, c.ID, c) + log.Fatalf("no response found %q %+v %+v", c.Method(), c.ID(), c) } func findgopls() string { @@ -298,7 +232,7 @@ func mimic(ctx context.Context) { log.Fatal(err) } stream := jsonrpc2.NewHeaderStream(fromServer, toServer) - rchan := make(chan *wireCombined, 10) // do we need buffering? + rchan := make(chan jsonrpc2.Message, 10) // do we need buffering? rdr := func() { for { buf, _, err := stream.Read(ctx) @@ -306,8 +240,8 @@ func mimic(ctx context.Context) { rchan <- nil // close it instead? return } - msg := &wireCombined{} - if err := json.Unmarshal(buf, msg); err != nil { + msg, err := jsonrpc2.DecodeMessage(buf) + if err != nil { log.Fatal(err) } rchan <- msg @@ -331,27 +265,26 @@ big: } done: for { - x := <-rchan - if x == nil { + msg := <-rchan + if msg == nil { break big } // if it's svrequest, do something // if it's clresponse or reporterr, add to seenids, and if it // is l.id, break out of the loop, and continue the outer loop - switch mt := msgType(x); mt { - case parse.SvRequest: - respond(ctx, x, stream) - continue done // still waiting - case parse.ClResponse, parse.ReportErr: - id := fmt.Sprint(x.ID) + + switch msg := msg.(type) { + case *jsonrpc2.Call: + if parse.FromServer(msg.Method()) { + respond(ctx, msg, stream) + continue done // still waiting + } + case *jsonrpc2.Response: + id := fmt.Sprint(msg.ID()) seenids[id] = true if id == l.ID { break done } - case parse.ToClient: - continue - default: - log.Fatalf("%s", mt) } } case parse.SvRequest: // not ours to send