131 lines
3.1 KiB
Go
131 lines
3.1 KiB
Go
package lsproto
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/microsoft/typescript-go/internal/json"
|
|
"github.com/microsoft/typescript-go/internal/jsonrpc"
|
|
)
|
|
|
|
// NewID creates an ID from an IntegerOrString value.
|
|
// This wrapper exists because lsproto has its own IntegerOrString type.
|
|
func NewID(rawValue IntegerOrString) *jsonrpc.ID {
|
|
if rawValue.String != nil {
|
|
return jsonrpc.NewIDString(*rawValue.String)
|
|
}
|
|
return jsonrpc.NewIDInt(*rawValue.Integer)
|
|
}
|
|
|
|
type Message struct {
|
|
Kind jsonrpc.MessageKind
|
|
msg any
|
|
}
|
|
|
|
func (m *Message) AsRequest() *RequestMessage {
|
|
return m.msg.(*RequestMessage)
|
|
}
|
|
|
|
func (m *Message) AsResponse() *ResponseMessage {
|
|
return m.msg.(*ResponseMessage)
|
|
}
|
|
|
|
func (m *Message) UnmarshalJSON(data []byte) error {
|
|
var raw struct {
|
|
JSONRPC jsonrpc.JSONRPCVersion `json:"jsonrpc"`
|
|
Method Method `json:"method"`
|
|
ID *jsonrpc.ID `json:"id,omitzero"`
|
|
Params json.Value `json:"params"`
|
|
// We don't have a method in the response, so we have no idea what to decode.
|
|
// Store the raw text and let the caller decode it.
|
|
Result json.Value `json:"result,omitzero"`
|
|
Error *jsonrpc.ResponseError `json:"error,omitzero"`
|
|
}
|
|
if err := json.Unmarshal(data, &raw); err != nil {
|
|
return fmt.Errorf("%w: %w", ErrorCodeInvalidRequest, err)
|
|
}
|
|
if raw.ID != nil && raw.Method == "" {
|
|
m.Kind = jsonrpc.MessageKindResponse
|
|
m.msg = &ResponseMessage{
|
|
ID: raw.ID,
|
|
Result: raw.Result,
|
|
Error: raw.Error,
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var params any
|
|
if len(raw.Params) > 0 {
|
|
params = raw.Params
|
|
}
|
|
|
|
if raw.ID == nil {
|
|
m.Kind = jsonrpc.MessageKindNotification
|
|
} else {
|
|
m.Kind = jsonrpc.MessageKindRequest
|
|
}
|
|
|
|
m.msg = &RequestMessage{
|
|
ID: raw.ID,
|
|
Method: raw.Method,
|
|
Params: params,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *Message) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(m.msg)
|
|
}
|
|
|
|
type RequestMessage struct {
|
|
JSONRPC jsonrpc.JSONRPCVersion `json:"jsonrpc"`
|
|
ID *jsonrpc.ID `json:"id,omitzero"`
|
|
Method Method `json:"method"`
|
|
Params any `json:"params,omitzero"`
|
|
}
|
|
|
|
func (r *RequestMessage) Message() *Message {
|
|
kind := jsonrpc.MessageKindRequest
|
|
if r.ID == nil {
|
|
kind = jsonrpc.MessageKindNotification
|
|
}
|
|
return &Message{
|
|
Kind: kind,
|
|
msg: r,
|
|
}
|
|
}
|
|
|
|
func (r *RequestMessage) UnmarshalJSON(data []byte) error {
|
|
var raw struct {
|
|
JSONRPC jsonrpc.JSONRPCVersion `json:"jsonrpc"`
|
|
ID *jsonrpc.ID `json:"id"`
|
|
Method Method `json:"method"`
|
|
Params json.Value `json:"params"`
|
|
}
|
|
if err := json.Unmarshal(data, &raw); err != nil {
|
|
return fmt.Errorf("%w: %w", ErrorCodeInvalidRequest, err)
|
|
}
|
|
|
|
r.ID = raw.ID
|
|
r.Method = raw.Method
|
|
if len(raw.Params) > 0 {
|
|
r.Params = raw.Params
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type ResponseMessage struct {
|
|
JSONRPC jsonrpc.JSONRPCVersion `json:"jsonrpc"`
|
|
ID *jsonrpc.ID `json:"id"`
|
|
Result any `json:"result,omitzero"`
|
|
Error *jsonrpc.ResponseError `json:"error,omitzero"`
|
|
}
|
|
|
|
func (r *ResponseMessage) Message() *Message {
|
|
return &Message{
|
|
Kind: jsonrpc.MessageKindResponse,
|
|
msg: r,
|
|
}
|
|
}
|