• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 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	"github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2"
23)
24
25type Client interface {
26	ShowMessage(context.Context, *ShowMessageParams) error
27	LogMessage(context.Context, *LogMessageParams) error
28	Event(context.Context, *interface{}) error
29	PublishDiagnostics(context.Context, *PublishDiagnosticsParams) error
30	WorkspaceFolders(context.Context) ([]WorkspaceFolder, error)
31	Configuration(context.Context, *ParamConfig) ([]interface{}, error)
32	RegisterCapability(context.Context, *RegistrationParams) error
33	UnregisterCapability(context.Context, *UnregistrationParams) error
34	ShowMessageRequest(context.Context, *ShowMessageRequestParams) (*MessageActionItem, error)
35	ApplyEdit(context.Context, *ApplyWorkspaceEditParams) (*ApplyWorkspaceEditResponse, error)
36}
37
38func (h clientHandler) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered bool) bool {
39	if delivered {
40		return false
41	}
42	if ctx.Err() != nil {
43		r.Reply(ctx, nil, jsonrpc2.NewErrorf(RequestCancelledError, ""))
44		return true
45	}
46	switch r.Method {
47	case "window/showMessage": // notif
48		var params ShowMessageParams
49		if err := json.Unmarshal(*r.Params, &params); err != nil {
50			sendParseError(ctx, r, err)
51			return true
52		}
53		if err := h.client.ShowMessage(ctx, &params); err != nil {
54			log.Printf("%v", err)
55		}
56		return true
57	case "window/logMessage": // notif
58		var params LogMessageParams
59		if err := json.Unmarshal(*r.Params, &params); err != nil {
60			sendParseError(ctx, r, err)
61			return true
62		}
63		if err := h.client.LogMessage(ctx, &params); err != nil {
64			log.Printf("%v", err)
65		}
66		return true
67	case "telemetry/event": // notif
68		var params interface{}
69		if err := json.Unmarshal(*r.Params, &params); err != nil {
70			sendParseError(ctx, r, err)
71			return true
72		}
73		if err := h.client.Event(ctx, &params); err != nil {
74			log.Printf("%v", err)
75		}
76		return true
77	case "textDocument/publishDiagnostics": // notif
78		var params PublishDiagnosticsParams
79		if err := json.Unmarshal(*r.Params, &params); err != nil {
80			sendParseError(ctx, r, err)
81			return true
82		}
83		if err := h.client.PublishDiagnostics(ctx, &params); err != nil {
84			log.Printf("%v", err)
85		}
86		return true
87	case "workspace/workspaceFolders": // req
88		if r.Params != nil {
89			r.Reply(ctx, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
90			return true
91		}
92		resp, err := h.client.WorkspaceFolders(ctx)
93		if err := r.Reply(ctx, resp, err); err != nil {
94			log.Printf("%v", err)
95		}
96		return true
97	case "workspace/configuration": // req
98		var params ParamConfig
99		if err := json.Unmarshal(*r.Params, &params); err != nil {
100			sendParseError(ctx, r, err)
101			return true
102		}
103		resp, err := h.client.Configuration(ctx, &params)
104		if err := r.Reply(ctx, resp, err); err != nil {
105			log.Printf("%v", err)
106		}
107		return true
108	case "client/registerCapability": // req
109		var params RegistrationParams
110		if err := json.Unmarshal(*r.Params, &params); err != nil {
111			sendParseError(ctx, r, err)
112			return true
113		}
114		err := h.client.RegisterCapability(ctx, &params)
115		if err := r.Reply(ctx, nil, err); err != nil {
116			log.Printf("%v", err)
117		}
118		return true
119	case "client/unregisterCapability": // req
120		var params UnregistrationParams
121		if err := json.Unmarshal(*r.Params, &params); err != nil {
122			sendParseError(ctx, r, err)
123			return true
124		}
125		err := h.client.UnregisterCapability(ctx, &params)
126		if err := r.Reply(ctx, nil, err); err != nil {
127			log.Printf("%v", err)
128		}
129		return true
130	case "window/showMessageRequest": // req
131		var params ShowMessageRequestParams
132		if err := json.Unmarshal(*r.Params, &params); err != nil {
133			sendParseError(ctx, r, err)
134			return true
135		}
136		resp, err := h.client.ShowMessageRequest(ctx, &params)
137		if err := r.Reply(ctx, resp, err); err != nil {
138			log.Printf("%v", err)
139		}
140		return true
141	case "workspace/applyEdit": // req
142		var params ApplyWorkspaceEditParams
143		if err := json.Unmarshal(*r.Params, &params); err != nil {
144			sendParseError(ctx, r, err)
145			return true
146		}
147		resp, err := h.client.ApplyEdit(ctx, &params)
148		if err := r.Reply(ctx, resp, err); err != nil {
149			log.Printf("%v", err)
150		}
151		return true
152
153	default:
154		return false
155	}
156}
157
158type clientDispatcher struct {
159	*jsonrpc2.Conn
160}
161
162func (s *clientDispatcher) ShowMessage(ctx context.Context, params *ShowMessageParams) error {
163	return s.Conn.Notify(ctx, "window/showMessage", params)
164}
165
166func (s *clientDispatcher) LogMessage(ctx context.Context, params *LogMessageParams) error {
167	return s.Conn.Notify(ctx, "window/logMessage", params)
168}
169
170func (s *clientDispatcher) Event(ctx context.Context, params *interface{}) error {
171	return s.Conn.Notify(ctx, "telemetry/event", params)
172}
173
174func (s *clientDispatcher) PublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) error {
175	return s.Conn.Notify(ctx, "textDocument/publishDiagnostics", params)
176}
177func (s *clientDispatcher) WorkspaceFolders(ctx context.Context) ([]WorkspaceFolder, error) {
178	var result []WorkspaceFolder
179	if err := s.Conn.Call(ctx, "workspace/workspaceFolders", nil, &result); err != nil {
180		return nil, err
181	}
182	return result, nil
183}
184
185func (s *clientDispatcher) Configuration(ctx context.Context, params *ParamConfig) ([]interface{}, error) {
186	var result []interface{}
187	if err := s.Conn.Call(ctx, "workspace/configuration", params, &result); err != nil {
188		return nil, err
189	}
190	return result, nil
191}
192
193func (s *clientDispatcher) RegisterCapability(ctx context.Context, params *RegistrationParams) error {
194	return s.Conn.Call(ctx, "client/registerCapability", params, nil) // Call, not Notify
195}
196
197func (s *clientDispatcher) UnregisterCapability(ctx context.Context, params *UnregistrationParams) error {
198	return s.Conn.Call(ctx, "client/unregisterCapability", params, nil) // Call, not Notify
199}
200
201func (s *clientDispatcher) ShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (*MessageActionItem, error) {
202	var result MessageActionItem
203	if err := s.Conn.Call(ctx, "window/showMessageRequest", params, &result); err != nil {
204		return nil, err
205	}
206	return &result, nil
207}
208
209func (s *clientDispatcher) ApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (*ApplyWorkspaceEditResponse, error) {
210	var result ApplyWorkspaceEditResponse
211	if err := s.Conn.Call(ctx, "workspace/applyEdit", params, &result); err != nil {
212		return nil, err
213	}
214	return &result, nil
215}
216
217// Types constructed to avoid structs as formal argument types
218type ParamConfig struct {
219	ConfigurationParams
220	PartialResultParams
221}
222