1fd4e5da5Sopenharmony_ci// Copyright 2019 The Go Authors.
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_cipackage protocol
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ciimport (
18fd4e5da5Sopenharmony_ci	"context"
19fd4e5da5Sopenharmony_ci	"encoding/json"
20fd4e5da5Sopenharmony_ci	"log"
21fd4e5da5Sopenharmony_ci
22fd4e5da5Sopenharmony_ci	"github.com/KhronosGroup/SPIRV-Tools/utils/vscode/src/lsp/jsonrpc2"
23fd4e5da5Sopenharmony_ci)
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_citype Client interface {
26fd4e5da5Sopenharmony_ci	ShowMessage(context.Context, *ShowMessageParams) error
27fd4e5da5Sopenharmony_ci	LogMessage(context.Context, *LogMessageParams) error
28fd4e5da5Sopenharmony_ci	Event(context.Context, *interface{}) error
29fd4e5da5Sopenharmony_ci	PublishDiagnostics(context.Context, *PublishDiagnosticsParams) error
30fd4e5da5Sopenharmony_ci	WorkspaceFolders(context.Context) ([]WorkspaceFolder, error)
31fd4e5da5Sopenharmony_ci	Configuration(context.Context, *ParamConfig) ([]interface{}, error)
32fd4e5da5Sopenharmony_ci	RegisterCapability(context.Context, *RegistrationParams) error
33fd4e5da5Sopenharmony_ci	UnregisterCapability(context.Context, *UnregistrationParams) error
34fd4e5da5Sopenharmony_ci	ShowMessageRequest(context.Context, *ShowMessageRequestParams) (*MessageActionItem, error)
35fd4e5da5Sopenharmony_ci	ApplyEdit(context.Context, *ApplyWorkspaceEditParams) (*ApplyWorkspaceEditResponse, error)
36fd4e5da5Sopenharmony_ci}
37fd4e5da5Sopenharmony_ci
38fd4e5da5Sopenharmony_cifunc (h clientHandler) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered bool) bool {
39fd4e5da5Sopenharmony_ci	if delivered {
40fd4e5da5Sopenharmony_ci		return false
41fd4e5da5Sopenharmony_ci	}
42fd4e5da5Sopenharmony_ci	if ctx.Err() != nil {
43fd4e5da5Sopenharmony_ci		r.Reply(ctx, nil, jsonrpc2.NewErrorf(RequestCancelledError, ""))
44fd4e5da5Sopenharmony_ci		return true
45fd4e5da5Sopenharmony_ci	}
46fd4e5da5Sopenharmony_ci	switch r.Method {
47fd4e5da5Sopenharmony_ci	case "window/showMessage": // notif
48fd4e5da5Sopenharmony_ci		var params ShowMessageParams
49fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
50fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
51fd4e5da5Sopenharmony_ci			return true
52fd4e5da5Sopenharmony_ci		}
53fd4e5da5Sopenharmony_ci		if err := h.client.ShowMessage(ctx, &params); err != nil {
54fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
55fd4e5da5Sopenharmony_ci		}
56fd4e5da5Sopenharmony_ci		return true
57fd4e5da5Sopenharmony_ci	case "window/logMessage": // notif
58fd4e5da5Sopenharmony_ci		var params LogMessageParams
59fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
60fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
61fd4e5da5Sopenharmony_ci			return true
62fd4e5da5Sopenharmony_ci		}
63fd4e5da5Sopenharmony_ci		if err := h.client.LogMessage(ctx, &params); err != nil {
64fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
65fd4e5da5Sopenharmony_ci		}
66fd4e5da5Sopenharmony_ci		return true
67fd4e5da5Sopenharmony_ci	case "telemetry/event": // notif
68fd4e5da5Sopenharmony_ci		var params interface{}
69fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
70fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
71fd4e5da5Sopenharmony_ci			return true
72fd4e5da5Sopenharmony_ci		}
73fd4e5da5Sopenharmony_ci		if err := h.client.Event(ctx, &params); err != nil {
74fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
75fd4e5da5Sopenharmony_ci		}
76fd4e5da5Sopenharmony_ci		return true
77fd4e5da5Sopenharmony_ci	case "textDocument/publishDiagnostics": // notif
78fd4e5da5Sopenharmony_ci		var params PublishDiagnosticsParams
79fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
80fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
81fd4e5da5Sopenharmony_ci			return true
82fd4e5da5Sopenharmony_ci		}
83fd4e5da5Sopenharmony_ci		if err := h.client.PublishDiagnostics(ctx, &params); err != nil {
84fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
85fd4e5da5Sopenharmony_ci		}
86fd4e5da5Sopenharmony_ci		return true
87fd4e5da5Sopenharmony_ci	case "workspace/workspaceFolders": // req
88fd4e5da5Sopenharmony_ci		if r.Params != nil {
89fd4e5da5Sopenharmony_ci			r.Reply(ctx, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
90fd4e5da5Sopenharmony_ci			return true
91fd4e5da5Sopenharmony_ci		}
92fd4e5da5Sopenharmony_ci		resp, err := h.client.WorkspaceFolders(ctx)
93fd4e5da5Sopenharmony_ci		if err := r.Reply(ctx, resp, err); err != nil {
94fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
95fd4e5da5Sopenharmony_ci		}
96fd4e5da5Sopenharmony_ci		return true
97fd4e5da5Sopenharmony_ci	case "workspace/configuration": // req
98fd4e5da5Sopenharmony_ci		var params ParamConfig
99fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
100fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
101fd4e5da5Sopenharmony_ci			return true
102fd4e5da5Sopenharmony_ci		}
103fd4e5da5Sopenharmony_ci		resp, err := h.client.Configuration(ctx, &params)
104fd4e5da5Sopenharmony_ci		if err := r.Reply(ctx, resp, err); err != nil {
105fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
106fd4e5da5Sopenharmony_ci		}
107fd4e5da5Sopenharmony_ci		return true
108fd4e5da5Sopenharmony_ci	case "client/registerCapability": // req
109fd4e5da5Sopenharmony_ci		var params RegistrationParams
110fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
111fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
112fd4e5da5Sopenharmony_ci			return true
113fd4e5da5Sopenharmony_ci		}
114fd4e5da5Sopenharmony_ci		err := h.client.RegisterCapability(ctx, &params)
115fd4e5da5Sopenharmony_ci		if err := r.Reply(ctx, nil, err); err != nil {
116fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
117fd4e5da5Sopenharmony_ci		}
118fd4e5da5Sopenharmony_ci		return true
119fd4e5da5Sopenharmony_ci	case "client/unregisterCapability": // req
120fd4e5da5Sopenharmony_ci		var params UnregistrationParams
121fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
122fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
123fd4e5da5Sopenharmony_ci			return true
124fd4e5da5Sopenharmony_ci		}
125fd4e5da5Sopenharmony_ci		err := h.client.UnregisterCapability(ctx, &params)
126fd4e5da5Sopenharmony_ci		if err := r.Reply(ctx, nil, err); err != nil {
127fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
128fd4e5da5Sopenharmony_ci		}
129fd4e5da5Sopenharmony_ci		return true
130fd4e5da5Sopenharmony_ci	case "window/showMessageRequest": // req
131fd4e5da5Sopenharmony_ci		var params ShowMessageRequestParams
132fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
133fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
134fd4e5da5Sopenharmony_ci			return true
135fd4e5da5Sopenharmony_ci		}
136fd4e5da5Sopenharmony_ci		resp, err := h.client.ShowMessageRequest(ctx, &params)
137fd4e5da5Sopenharmony_ci		if err := r.Reply(ctx, resp, err); err != nil {
138fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
139fd4e5da5Sopenharmony_ci		}
140fd4e5da5Sopenharmony_ci		return true
141fd4e5da5Sopenharmony_ci	case "workspace/applyEdit": // req
142fd4e5da5Sopenharmony_ci		var params ApplyWorkspaceEditParams
143fd4e5da5Sopenharmony_ci		if err := json.Unmarshal(*r.Params, &params); err != nil {
144fd4e5da5Sopenharmony_ci			sendParseError(ctx, r, err)
145fd4e5da5Sopenharmony_ci			return true
146fd4e5da5Sopenharmony_ci		}
147fd4e5da5Sopenharmony_ci		resp, err := h.client.ApplyEdit(ctx, &params)
148fd4e5da5Sopenharmony_ci		if err := r.Reply(ctx, resp, err); err != nil {
149fd4e5da5Sopenharmony_ci			log.Printf("%v", err)
150fd4e5da5Sopenharmony_ci		}
151fd4e5da5Sopenharmony_ci		return true
152fd4e5da5Sopenharmony_ci
153fd4e5da5Sopenharmony_ci	default:
154fd4e5da5Sopenharmony_ci		return false
155fd4e5da5Sopenharmony_ci	}
156fd4e5da5Sopenharmony_ci}
157fd4e5da5Sopenharmony_ci
158fd4e5da5Sopenharmony_citype clientDispatcher struct {
159fd4e5da5Sopenharmony_ci	*jsonrpc2.Conn
160fd4e5da5Sopenharmony_ci}
161fd4e5da5Sopenharmony_ci
162fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) ShowMessage(ctx context.Context, params *ShowMessageParams) error {
163fd4e5da5Sopenharmony_ci	return s.Conn.Notify(ctx, "window/showMessage", params)
164fd4e5da5Sopenharmony_ci}
165fd4e5da5Sopenharmony_ci
166fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) LogMessage(ctx context.Context, params *LogMessageParams) error {
167fd4e5da5Sopenharmony_ci	return s.Conn.Notify(ctx, "window/logMessage", params)
168fd4e5da5Sopenharmony_ci}
169fd4e5da5Sopenharmony_ci
170fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) Event(ctx context.Context, params *interface{}) error {
171fd4e5da5Sopenharmony_ci	return s.Conn.Notify(ctx, "telemetry/event", params)
172fd4e5da5Sopenharmony_ci}
173fd4e5da5Sopenharmony_ci
174fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) PublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) error {
175fd4e5da5Sopenharmony_ci	return s.Conn.Notify(ctx, "textDocument/publishDiagnostics", params)
176fd4e5da5Sopenharmony_ci}
177fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) WorkspaceFolders(ctx context.Context) ([]WorkspaceFolder, error) {
178fd4e5da5Sopenharmony_ci	var result []WorkspaceFolder
179fd4e5da5Sopenharmony_ci	if err := s.Conn.Call(ctx, "workspace/workspaceFolders", nil, &result); err != nil {
180fd4e5da5Sopenharmony_ci		return nil, err
181fd4e5da5Sopenharmony_ci	}
182fd4e5da5Sopenharmony_ci	return result, nil
183fd4e5da5Sopenharmony_ci}
184fd4e5da5Sopenharmony_ci
185fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) Configuration(ctx context.Context, params *ParamConfig) ([]interface{}, error) {
186fd4e5da5Sopenharmony_ci	var result []interface{}
187fd4e5da5Sopenharmony_ci	if err := s.Conn.Call(ctx, "workspace/configuration", params, &result); err != nil {
188fd4e5da5Sopenharmony_ci		return nil, err
189fd4e5da5Sopenharmony_ci	}
190fd4e5da5Sopenharmony_ci	return result, nil
191fd4e5da5Sopenharmony_ci}
192fd4e5da5Sopenharmony_ci
193fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) RegisterCapability(ctx context.Context, params *RegistrationParams) error {
194fd4e5da5Sopenharmony_ci	return s.Conn.Call(ctx, "client/registerCapability", params, nil) // Call, not Notify
195fd4e5da5Sopenharmony_ci}
196fd4e5da5Sopenharmony_ci
197fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) UnregisterCapability(ctx context.Context, params *UnregistrationParams) error {
198fd4e5da5Sopenharmony_ci	return s.Conn.Call(ctx, "client/unregisterCapability", params, nil) // Call, not Notify
199fd4e5da5Sopenharmony_ci}
200fd4e5da5Sopenharmony_ci
201fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) ShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (*MessageActionItem, error) {
202fd4e5da5Sopenharmony_ci	var result MessageActionItem
203fd4e5da5Sopenharmony_ci	if err := s.Conn.Call(ctx, "window/showMessageRequest", params, &result); err != nil {
204fd4e5da5Sopenharmony_ci		return nil, err
205fd4e5da5Sopenharmony_ci	}
206fd4e5da5Sopenharmony_ci	return &result, nil
207fd4e5da5Sopenharmony_ci}
208fd4e5da5Sopenharmony_ci
209fd4e5da5Sopenharmony_cifunc (s *clientDispatcher) ApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (*ApplyWorkspaceEditResponse, error) {
210fd4e5da5Sopenharmony_ci	var result ApplyWorkspaceEditResponse
211fd4e5da5Sopenharmony_ci	if err := s.Conn.Call(ctx, "workspace/applyEdit", params, &result); err != nil {
212fd4e5da5Sopenharmony_ci		return nil, err
213fd4e5da5Sopenharmony_ci	}
214fd4e5da5Sopenharmony_ci	return &result, nil
215fd4e5da5Sopenharmony_ci}
216fd4e5da5Sopenharmony_ci
217fd4e5da5Sopenharmony_ci// Types constructed to avoid structs as formal argument types
218fd4e5da5Sopenharmony_citype ParamConfig struct {
219fd4e5da5Sopenharmony_ci	ConfigurationParams
220fd4e5da5Sopenharmony_ci	PartialResultParams
221fd4e5da5Sopenharmony_ci}
222