mirror of
https://github.com/golang/go
synced 2024-11-18 10:14:45 -07:00
internal/lsp: switch the protocol logger to use the new jsonrpc2 message types
This saves it from having to know the wire format and understand the decoding tricks. Change-Id: I1f3ef3345ffee736a9d104f8ebfb436404d737c0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/228721 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
ca8a290ca5
commit
9f075f7bfe
@ -2,7 +2,6 @@ package protocol
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
@ -41,23 +40,6 @@ func (s *loggingStream) Write(ctx context.Context, data []byte) (int64, error) {
|
||||
return count, err
|
||||
}
|
||||
|
||||
// wireCombined has all the fields of both Request and Response.
|
||||
// We can decode this and then work out which it is.
|
||||
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 *wireError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type wireError struct {
|
||||
Code int64 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data *json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
type req struct {
|
||||
method string
|
||||
start time.Time
|
||||
@ -112,19 +94,18 @@ func (m *mapped) setServer(id string, r req) {
|
||||
|
||||
const eor = "\r\n\r\n\r\n"
|
||||
|
||||
func logCommon(outfd io.Writer, data []byte) (*wireCombined, time.Time, string) {
|
||||
func logCommon(outfd io.Writer, data []byte) (jsonrpc2.Message, time.Time, string) {
|
||||
if outfd == nil {
|
||||
return nil, time.Time{}, ""
|
||||
}
|
||||
var v wireCombined
|
||||
err := json.Unmarshal(data, &v)
|
||||
v, err := jsonrpc2.DecodeMessage(data)
|
||||
if err != nil {
|
||||
fmt.Fprintf(outfd, "Unmarshal %v\n", err)
|
||||
panic(err) // do better
|
||||
}
|
||||
tm := time.Now()
|
||||
tmfmt := tm.Format("15:04:05.000 PM")
|
||||
return &v, tm, tmfmt
|
||||
return v, tm, tmfmt
|
||||
}
|
||||
|
||||
// logOut and logIn could be combined. "received"<->"Sending", serverCalls<->clientCalls
|
||||
@ -132,111 +113,65 @@ func logCommon(outfd io.Writer, data []byte) (*wireCombined, time.Time, string)
|
||||
|
||||
// Writing a message to the client, log it
|
||||
func logOut(outfd io.Writer, data []byte) {
|
||||
v, tm, tmfmt := logCommon(outfd, data)
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
id := fmt.Sprint(v.ID)
|
||||
if v.Error != nil {
|
||||
fmt.Fprintf(outfd, "[Error - %s] Received #%s %s%s", tmfmt, id, v.Error.Message, eor)
|
||||
msg, tm, tmfmt := logCommon(outfd, data)
|
||||
if msg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
buf := strings.Builder{}
|
||||
fmt.Fprintf(&buf, "[Trace - %s] ", tmfmt) // common beginning
|
||||
if v.ID != nil && v.Method != "" && v.Params != nil {
|
||||
fmt.Fprintf(&buf, "Received request '%s - (%s)'.\n", v.Method, id)
|
||||
fmt.Fprintf(&buf, "Params: %s%s", *v.Params, eor)
|
||||
maps.setServer(id, req{method: v.Method, start: tm})
|
||||
} else if v.ID != nil && v.Method == "" && v.Params == nil {
|
||||
switch msg := msg.(type) {
|
||||
case *jsonrpc2.Call:
|
||||
id := fmt.Sprint(msg.ID())
|
||||
fmt.Fprintf(&buf, "Received request '%s - (%s)'.\n", msg.Method(), id)
|
||||
fmt.Fprintf(&buf, "Params: %s%s", msg.Params(), eor)
|
||||
maps.setServer(id, req{method: msg.Method(), start: tm})
|
||||
case *jsonrpc2.Notification:
|
||||
fmt.Fprintf(&buf, "Received notification '%s'.\n", msg.Method())
|
||||
fmt.Fprintf(&buf, "Params: %s%s", msg.Params(), eor)
|
||||
case *jsonrpc2.Response:
|
||||
id := fmt.Sprint(msg.ID())
|
||||
if err := msg.Err(); err != nil {
|
||||
fmt.Fprintf(outfd, "[Error - %s] Received #%s %s%s", tmfmt, id, err, eor)
|
||||
return
|
||||
}
|
||||
cc := maps.client(id, true)
|
||||
elapsed := tm.Sub(cc.start)
|
||||
fmt.Fprintf(&buf, "Received response '%s - (%s)' in %dms.\n",
|
||||
cc.method, id, elapsed/time.Millisecond)
|
||||
if v.Result == nil {
|
||||
fmt.Fprintf(&buf, "Result: {}%s", eor)
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "Result: %s%s", string(*v.Result), eor)
|
||||
}
|
||||
} else if v.ID == nil && v.Method != "" && v.Params != nil {
|
||||
p := "null"
|
||||
if v.Params != nil {
|
||||
p = string(*v.Params)
|
||||
}
|
||||
fmt.Fprintf(&buf, "Received notification '%s'.\n", v.Method)
|
||||
fmt.Fprintf(&buf, "Params: %s%s", p, eor)
|
||||
} else { // for completeness, as it should never happen
|
||||
buf = strings.Builder{} // undo common Trace
|
||||
fmt.Fprintf(&buf, "[Error - %s] on write ID?%v method:%q Params:%v Result:%v Error:%v%s",
|
||||
tmfmt, v.ID != nil, v.Method, v.Params != nil,
|
||||
v.Result != nil, v.Error != nil, eor)
|
||||
p := "null"
|
||||
if v.Params != nil {
|
||||
p = string(*v.Params)
|
||||
}
|
||||
r := "null"
|
||||
if v.Result != nil {
|
||||
r = string(*v.Result)
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s\n%s\n%s%s", p, r, v.Error.Message, eor)
|
||||
fmt.Fprintf(&buf, "Result: %s%s", msg.Result(), eor)
|
||||
}
|
||||
outfd.Write([]byte(buf.String()))
|
||||
}
|
||||
|
||||
// Got a message from the client, log it
|
||||
func logIn(outfd io.Writer, data []byte) {
|
||||
v, tm, tmfmt := logCommon(outfd, data)
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
id := fmt.Sprint(v.ID)
|
||||
// ID Method Params => Sending request
|
||||
// ID !Method Result(might be null, but !Params) => Sending response (could we get an Error?)
|
||||
// !ID Method Params => Sending notification
|
||||
if v.Error != nil { // does this ever happen?
|
||||
fmt.Fprintf(outfd, "[Error - %s] Sent #%s %s%s", tmfmt, id, v.Error.Message, eor)
|
||||
msg, tm, tmfmt := logCommon(outfd, data)
|
||||
if msg == nil {
|
||||
return
|
||||
}
|
||||
buf := strings.Builder{}
|
||||
fmt.Fprintf(&buf, "[Trace - %s] ", tmfmt) // common beginning
|
||||
if v.ID != nil && v.Method != "" && (v.Params != nil || v.Method == "shutdown") {
|
||||
fmt.Fprintf(&buf, "Sending request '%s - (%s)'.\n", v.Method, id)
|
||||
x := "{}"
|
||||
if v.Params != nil {
|
||||
x = string(*v.Params)
|
||||
switch msg := msg.(type) {
|
||||
case *jsonrpc2.Call:
|
||||
id := fmt.Sprint(msg.ID())
|
||||
fmt.Fprintf(&buf, "Sending request '%s - (%s)'.\n", msg.Method(), id)
|
||||
fmt.Fprintf(&buf, "Params: %s%s", msg.Params(), eor)
|
||||
maps.setServer(id, req{method: msg.Method(), start: tm})
|
||||
case *jsonrpc2.Notification:
|
||||
fmt.Fprintf(&buf, "Sending notification '%s'.\n", msg.Method())
|
||||
fmt.Fprintf(&buf, "Params: %s%s", msg.Params(), eor)
|
||||
case *jsonrpc2.Response:
|
||||
id := fmt.Sprint(msg.ID())
|
||||
if err := msg.Err(); err != nil {
|
||||
fmt.Fprintf(outfd, "[Error - %s] Sent #%s %s%s", tmfmt, id, err, eor)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(&buf, "Params: %s%s", x, eor)
|
||||
maps.setClient(id, req{method: v.Method, start: tm})
|
||||
} else if v.ID != nil && v.Method == "" && v.Params == nil {
|
||||
sc := maps.server(id, true)
|
||||
elapsed := tm.Sub(sc.start)
|
||||
fmt.Fprintf(&buf, "Sending response '%s - (%s)' took %dms.\n",
|
||||
sc.method, id, elapsed/time.Millisecond)
|
||||
if v.Result == nil {
|
||||
fmt.Fprintf(&buf, "Result: {}%s", eor)
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "Result: %s%s", string(*v.Result), eor)
|
||||
}
|
||||
} else if v.ID == nil && v.Method != "" {
|
||||
p := "null"
|
||||
if v.Params != nil {
|
||||
p = string(*v.Params)
|
||||
}
|
||||
fmt.Fprintf(&buf, "Sending notification '%s'.\n", v.Method)
|
||||
fmt.Fprintf(&buf, "Params: %s%s", p, eor)
|
||||
} else { // for completeness, as it should never happen
|
||||
buf = strings.Builder{} // undo common Trace
|
||||
fmt.Fprintf(&buf, "[Error - %s] on read ID?%v method:%q Params:%v Result:%v Error:%v%s",
|
||||
tmfmt, v.ID != nil, v.Method, v.Params != nil,
|
||||
v.Result != nil, v.Error != nil, eor)
|
||||
p := "null"
|
||||
if v.Params != nil {
|
||||
p = string(*v.Params)
|
||||
}
|
||||
r := "null"
|
||||
if v.Result != nil {
|
||||
r = string(*v.Result)
|
||||
}
|
||||
fmt.Fprintf(&buf, "%s\n%s\n%s%s", p, r, v.Error.Message, eor)
|
||||
cc := maps.client(id, true)
|
||||
elapsed := tm.Sub(cc.start)
|
||||
fmt.Fprintf(&buf, "Sending response '%s - (%s)' in %dms.\n",
|
||||
cc.method, id, elapsed/time.Millisecond)
|
||||
fmt.Fprintf(&buf, "Result: %s%s", msg.Result(), eor)
|
||||
}
|
||||
outfd.Write([]byte(buf.String()))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user