@@ -26,56 +26,121 @@ static bool mapRaw(const json::Value &Params, StringLiteral Prop,
2626 return true ;
2727}
2828
29+ static llvm::json::Value toJSON (const Id &Id) {
30+ if (const int64_t *I = std::get_if<int64_t >(&Id))
31+ return json::Value (*I);
32+ if (const std::string *S = std::get_if<std::string>(&Id))
33+ return json::Value (*S);
34+ llvm_unreachable (" unexpected type in protocol::Id" );
35+ }
36+
37+ static bool mapId (const llvm::json::Value &V, StringLiteral Prop, Id &Id,
38+ llvm::json::Path P) {
39+ const auto *O = V.getAsObject ();
40+ if (!O) {
41+ P.report (" expected object" );
42+ return false ;
43+ }
44+
45+ const auto *E = O->get (Prop);
46+ if (!E) {
47+ P.field (Prop).report (" not found" );
48+ return false ;
49+ }
50+
51+ if (auto S = E->getAsString ()) {
52+ Id = S->str ();
53+ return true ;
54+ }
55+
56+ if (auto I = E->getAsInteger ()) {
57+ Id = *I;
58+ return true ;
59+ }
60+
61+ P.report (" expected string or number" );
62+ return false ;
63+ }
64+
2965llvm::json::Value toJSON (const Request &R) {
30- json::Object Result{{" jsonrpc" , " 2.0" }, {" id" , R.id }, {" method" , R.method }};
66+ json::Object Result{
67+ {" jsonrpc" , " 2.0" }, {" id" , toJSON (R.id )}, {" method" , R.method }};
3168 if (R.params )
3269 Result.insert ({" params" , R.params });
3370 return Result;
3471}
3572
3673bool fromJSON (const llvm::json::Value &V, Request &R, llvm::json::Path P) {
3774 llvm::json::ObjectMapper O (V, P);
38- if (!O || !O.map (" id" , R.id ) || !O.map (" method" , R.method ))
39- return false ;
40- return mapRaw (V, " params" , R.params , P);
41- }
42-
43- llvm::json::Value toJSON (const ErrorInfo &EI) {
44- llvm::json::Object Result{{" code" , EI.code }, {" message" , EI.message }};
45- if (!EI.data .empty ())
46- Result.insert ({" data" , EI.data });
47- return Result;
75+ return O && mapId (V, " id" , R.id , P) && O.map (" method" , R.method ) &&
76+ mapRaw (V, " params" , R.params , P);
4877}
4978
50- bool fromJSON (const llvm::json::Value &V, ErrorInfo &EI, llvm::json::Path P) {
51- llvm::json::ObjectMapper O (V, P);
52- return O && O.map (" code" , EI.code ) && O.map (" message" , EI.message ) &&
53- O.mapOptional (" data" , EI.data );
79+ bool operator ==(const Request &a, const Request &b) {
80+ return a.id == b.id && a.method == b.method && a.params == b.params ;
5481}
5582
5683llvm::json::Value toJSON (const Error &E) {
57- return json::Object{{" jsonrpc" , " 2.0" }, {" id" , E.id }, {" error" , E.error }};
84+ llvm::json::Object Result{{" code" , E.code }, {" message" , E.message }};
85+ if (E.data )
86+ Result.insert ({" data" , *E.data });
87+ return Result;
5888}
5989
6090bool fromJSON (const llvm::json::Value &V, Error &E, llvm::json::Path P) {
6191 llvm::json::ObjectMapper O (V, P);
62- return O && O.map (" id" , E.id ) && O.map (" error" , E.error );
92+ return O && O.map (" code" , E.code ) && O.map (" message" , E.message ) &&
93+ mapRaw (V, " data" , E.data , P);
94+ }
95+
96+ bool operator ==(const Error &a, const Error &b) {
97+ return a.code == b.code && a.message == b.message && a.data == b.data ;
6398}
6499
65100llvm::json::Value toJSON (const Response &R) {
66- llvm::json::Object Result{{" jsonrpc" , " 2.0" }, {" id" , R.id }};
67- if (R.result )
68- Result.insert ({" result" , R.result });
69- if (R.error )
70- Result.insert ({" error" , R.error });
101+ llvm::json::Object Result{{" jsonrpc" , " 2.0" }, {" id" , toJSON (R.id )}};
102+
103+ if (const Error *error = std::get_if<Error>(&R.result ))
104+ Result.insert ({" error" , *error});
105+ if (const json::Value *result = std::get_if<json::Value>(&R.result ))
106+ Result.insert ({" result" , *result});
71107 return Result;
72108}
73109
74110bool fromJSON (const llvm::json::Value &V, Response &R, llvm::json::Path P) {
75- llvm::json::ObjectMapper O (V, P);
76- if (!O || !O.map (" id" , R.id ) || !O.map (" error" , R.error ))
111+ const json::Object *E = V.getAsObject ();
112+ if (!E) {
113+ P.report (" expected object" );
114+ return false ;
115+ }
116+
117+ const json::Value *result = E->get (" result" );
118+ const json::Value *raw_error = E->get (" error" );
119+
120+ if (result && raw_error) {
121+ P.report (" 'result' and 'error' fields are mutually exclusive" );
77122 return false ;
78- return mapRaw (V, " result" , R.result , P);
123+ }
124+
125+ if (!result && !raw_error) {
126+ P.report (" 'result' or 'error' fields are required'" );
127+ return false ;
128+ }
129+
130+ if (result) {
131+ R.result = std::move (*result);
132+ } else {
133+ Error error;
134+ if (!fromJSON (*raw_error, error, P))
135+ return false ;
136+ R.result = std::move (error);
137+ }
138+
139+ return mapId (V, " id" , R.id , P);
140+ }
141+
142+ bool operator ==(const Response &a, const Response &b) {
143+ return a.id == b.id && a.result == b.result ;
79144}
80145
81146llvm::json::Value toJSON (const Notification &N) {
@@ -97,6 +162,10 @@ bool fromJSON(const llvm::json::Value &V, Notification &N, llvm::json::Path P) {
97162 return true ;
98163}
99164
165+ bool operator ==(const Notification &a, const Notification &b) {
166+ return a.method == b.method && a.params == b.params ;
167+ }
168+
100169llvm::json::Value toJSON (const ToolCapability &TC) {
101170 return llvm::json::Object{{" listChanged" , TC.listChanged }};
102171}
@@ -235,24 +304,16 @@ bool fromJSON(const llvm::json::Value &V, Message &M, llvm::json::Path P) {
235304 return true ;
236305 }
237306
238- if (O->get (" error" )) {
239- Error E;
240- if (!fromJSON (V, E, P))
241- return false ;
242- M = std::move (E);
243- return true ;
244- }
245-
246- if (O->get (" result" )) {
247- Response R;
307+ if (O->get (" method" )) {
308+ Request R;
248309 if (!fromJSON (V, R, P))
249310 return false ;
250311 M = std::move (R);
251312 return true ;
252313 }
253314
254- if (O->get (" method " )) {
255- Request R;
315+ if (O->get (" result " ) || O-> get ( " error " )) {
316+ Response R;
256317 if (!fromJSON (V, R, P))
257318 return false ;
258319 M = std::move (R);
0 commit comments