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, ¶ms); err != nil { 50fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 51fd4e5da5Sopenharmony_ci return true 52fd4e5da5Sopenharmony_ci } 53fd4e5da5Sopenharmony_ci if err := h.client.ShowMessage(ctx, ¶ms); 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, ¶ms); err != nil { 60fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 61fd4e5da5Sopenharmony_ci return true 62fd4e5da5Sopenharmony_ci } 63fd4e5da5Sopenharmony_ci if err := h.client.LogMessage(ctx, ¶ms); 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, ¶ms); err != nil { 70fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 71fd4e5da5Sopenharmony_ci return true 72fd4e5da5Sopenharmony_ci } 73fd4e5da5Sopenharmony_ci if err := h.client.Event(ctx, ¶ms); 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, ¶ms); err != nil { 80fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 81fd4e5da5Sopenharmony_ci return true 82fd4e5da5Sopenharmony_ci } 83fd4e5da5Sopenharmony_ci if err := h.client.PublishDiagnostics(ctx, ¶ms); 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, ¶ms); err != nil { 100fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 101fd4e5da5Sopenharmony_ci return true 102fd4e5da5Sopenharmony_ci } 103fd4e5da5Sopenharmony_ci resp, err := h.client.Configuration(ctx, ¶ms) 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, ¶ms); err != nil { 111fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 112fd4e5da5Sopenharmony_ci return true 113fd4e5da5Sopenharmony_ci } 114fd4e5da5Sopenharmony_ci err := h.client.RegisterCapability(ctx, ¶ms) 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, ¶ms); err != nil { 122fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 123fd4e5da5Sopenharmony_ci return true 124fd4e5da5Sopenharmony_ci } 125fd4e5da5Sopenharmony_ci err := h.client.UnregisterCapability(ctx, ¶ms) 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, ¶ms); err != nil { 133fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 134fd4e5da5Sopenharmony_ci return true 135fd4e5da5Sopenharmony_ci } 136fd4e5da5Sopenharmony_ci resp, err := h.client.ShowMessageRequest(ctx, ¶ms) 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, ¶ms); err != nil { 144fd4e5da5Sopenharmony_ci sendParseError(ctx, r, err) 145fd4e5da5Sopenharmony_ci return true 146fd4e5da5Sopenharmony_ci } 147fd4e5da5Sopenharmony_ci resp, err := h.client.ApplyEdit(ctx, ¶ms) 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