Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / internal / jsonrpc2 / messages.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package jsonrpc2
6
7 import (
8         "encoding/json"
9         "fmt"
10
11         errors "golang.org/x/xerrors"
12 )
13
14 // Message is the interface to all jsonrpc2 message types.
15 // They share no common functionality, but are a closed set of concrete types
16 // that are allowed to implement this interface. The message types are *Call,
17 // *Notification and *Response.
18 type Message interface {
19         // isJSONRPC2Message is used to make the set of message implementations a
20         // closed set.
21         isJSONRPC2Message()
22 }
23
24 // Request is the shared interface to jsonrpc2 messages that request
25 // a method be invoked.
26 // The request types are a closed set of *Call and *Notification.
27 type Request interface {
28         Message
29         // Method is a string containing the method name to invoke.
30         Method() string
31         // Params is either a struct or an array with the parameters of the method.
32         Params() json.RawMessage
33         // isJSONRPC2Request is used to make the set of request implementations closed.
34         isJSONRPC2Request()
35 }
36
37 // Notification is a request for which a response cannot occur, and as such
38 // it has not ID.
39 type Notification struct {
40         // Method is a string containing the method name to invoke.
41         method string
42         params json.RawMessage
43 }
44
45 // Call is a request that expects a response.
46 // The response will have a matching ID.
47 type Call struct {
48         // Method is a string containing the method name to invoke.
49         method string
50         // Params is either a struct or an array with the parameters of the method.
51         params json.RawMessage
52         // id of this request, used to tie the Response back to the request.
53         id ID
54 }
55
56 // Response is a reply to a Call.
57 // It will have the same ID as the call it is a response to.
58 type Response struct {
59         // result is the content of the response.
60         result json.RawMessage
61         // err is set only if the call failed.
62         err error
63         // ID of the request this is a response to.
64         id ID
65 }
66
67 // NewNotification constructs a new Notification message for the supplied
68 // method and parameters.
69 func NewNotification(method string, params interface{}) (*Notification, error) {
70         p, merr := marshalToRaw(params)
71         return &Notification{method: method, params: p}, merr
72 }
73
74 func (msg *Notification) Method() string          { return msg.method }
75 func (msg *Notification) Params() json.RawMessage { return msg.params }
76 func (msg *Notification) isJSONRPC2Message()      {}
77 func (msg *Notification) isJSONRPC2Request()      {}
78
79 func (n *Notification) MarshalJSON() ([]byte, error) {
80         msg := wireRequest{Method: n.method, Params: &n.params}
81         data, err := json.Marshal(msg)
82         if err != nil {
83                 return data, fmt.Errorf("marshaling notification: %w", err)
84         }
85         return data, nil
86 }
87
88 func (n *Notification) UnmarshalJSON(data []byte) error {
89         msg := wireRequest{}
90         if err := json.Unmarshal(data, &msg); err != nil {
91                 return fmt.Errorf("unmarshaling notification: %w", err)
92         }
93         n.method = msg.Method
94         if msg.Params != nil {
95                 n.params = *msg.Params
96         }
97         return nil
98 }
99
100 // NewCall constructs a new Call message for the supplied ID, method and
101 // parameters.
102 func NewCall(id ID, method string, params interface{}) (*Call, error) {
103         p, merr := marshalToRaw(params)
104         return &Call{id: id, method: method, params: p}, merr
105 }
106
107 func (msg *Call) Method() string          { return msg.method }
108 func (msg *Call) Params() json.RawMessage { return msg.params }
109 func (msg *Call) ID() ID                  { return msg.id }
110 func (msg *Call) isJSONRPC2Message()      {}
111 func (msg *Call) isJSONRPC2Request()      {}
112
113 func (c *Call) MarshalJSON() ([]byte, error) {
114         msg := wireRequest{Method: c.method, Params: &c.params, ID: &c.id}
115         data, err := json.Marshal(msg)
116         if err != nil {
117                 return data, fmt.Errorf("marshaling call: %w", err)
118         }
119         return data, nil
120 }
121
122 func (c *Call) UnmarshalJSON(data []byte) error {
123         msg := wireRequest{}
124         if err := json.Unmarshal(data, &msg); err != nil {
125                 return fmt.Errorf("unmarshaling call: %w", err)
126         }
127         c.method = msg.Method
128         if msg.Params != nil {
129                 c.params = *msg.Params
130         }
131         if msg.ID != nil {
132                 c.id = *msg.ID
133         }
134         return nil
135 }
136
137 // NewResponse constructs a new Response message that is a reply to the
138 // supplied. If err is set result may be ignored.
139 func NewResponse(id ID, result interface{}, err error) (*Response, error) {
140         r, merr := marshalToRaw(result)
141         return &Response{id: id, result: r, err: err}, merr
142 }
143
144 func (msg *Response) ID() ID                  { return msg.id }
145 func (msg *Response) Result() json.RawMessage { return msg.result }
146 func (msg *Response) Err() error              { return msg.err }
147 func (msg *Response) isJSONRPC2Message()      {}
148
149 func (r *Response) MarshalJSON() ([]byte, error) {
150         msg := &wireResponse{Error: toWireError(r.err), ID: &r.id}
151         if msg.Error == nil {
152                 msg.Result = &r.result
153         }
154         data, err := json.Marshal(msg)
155         if err != nil {
156                 return data, fmt.Errorf("marshaling notification: %w", err)
157         }
158         return data, nil
159 }
160
161 func toWireError(err error) *wireError {
162         if err == nil {
163                 // no error, the response is complete
164                 return nil
165         }
166         if err, ok := err.(*wireError); ok {
167                 // already a wire error, just use it
168                 return err
169         }
170         result := &wireError{Message: err.Error()}
171         var wrapped *wireError
172         if errors.As(err, &wrapped) {
173                 // if we wrapped a wire error, keep the code from the wrapped error
174                 // but the message from the outer error
175                 result.Code = wrapped.Code
176         }
177         return result
178 }
179
180 func (r *Response) UnmarshalJSON(data []byte) error {
181         msg := wireResponse{}
182         if err := json.Unmarshal(data, &msg); err != nil {
183                 return fmt.Errorf("unmarshaling jsonrpc response: %w", err)
184         }
185         if msg.Result != nil {
186                 r.result = *msg.Result
187         }
188         if msg.Error != nil {
189                 r.err = msg.Error
190         }
191         if msg.ID != nil {
192                 r.id = *msg.ID
193         }
194         return nil
195 }
196
197 func DecodeMessage(data []byte) (Message, error) {
198         msg := wireCombined{}
199         if err := json.Unmarshal(data, &msg); err != nil {
200                 return nil, fmt.Errorf("unmarshaling jsonrpc message: %w", err)
201         }
202         if msg.Method == "" {
203                 // no method, should be a response
204                 if msg.ID == nil {
205                         return nil, ErrInvalidRequest
206                 }
207                 response := &Response{id: *msg.ID}
208                 if msg.Error != nil {
209                         response.err = msg.Error
210                 }
211                 if msg.Result != nil {
212                         response.result = *msg.Result
213                 }
214                 return response, nil
215         }
216         // has a method, must be a request
217         if msg.ID == nil {
218                 // request with no ID is a notify
219                 notify := &Notification{method: msg.Method}
220                 if msg.Params != nil {
221                         notify.params = *msg.Params
222                 }
223                 return notify, nil
224         }
225         // request with an ID, must be a call
226         call := &Call{method: msg.Method, id: *msg.ID}
227         if msg.Params != nil {
228                 call.params = *msg.Params
229         }
230         return call, nil
231 }
232
233 func marshalToRaw(obj interface{}) (json.RawMessage, error) {
234         data, err := json.Marshal(obj)
235         if err != nil {
236                 return json.RawMessage{}, err
237         }
238         return json.RawMessage(data), nil
239 }