blob: 172f77afb01fee1146d1f98268637ab6b70d1c9f [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===---------------------JSON.h --------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef utility_JSON_h_
10#define utility_JSON_h_
11
12#include "lldb/Utility/StringExtractor.h"
13
14#include <map>
15#include <memory>
16#include <string>
17#include <type_traits>
18#include <vector>
19
20#include <stdint.h>
21
22namespace lldb_private {
23class Stream;
24
25class JSONValue {
26public:
27 virtual void Write(Stream &s) = 0;
28
29 typedef std::shared_ptr<JSONValue> SP;
30
31 enum class Kind { String, Number, True, False, Null, Object, Array };
32
33 JSONValue(Kind k) : m_kind(k) {}
34
35 Kind GetKind() const { return m_kind; }
36
37 virtual ~JSONValue() = default;
38
39private:
40 const Kind m_kind;
41};
42
43class JSONString : public JSONValue {
44public:
45 JSONString();
46 JSONString(const char *s);
47 JSONString(const std::string &s);
48
49 JSONString(const JSONString &s) = delete;
50 JSONString &operator=(const JSONString &s) = delete;
51
52 void Write(Stream &s) override;
53
54 typedef std::shared_ptr<JSONString> SP;
55
56 std::string GetData() { return m_data; }
57
58 static bool classof(const JSONValue *V) {
59 return V->GetKind() == JSONValue::Kind::String;
60 }
61
62 ~JSONString() override = default;
63
64private:
65 static std::string json_string_quote_metachars(const std::string &);
66
67 std::string m_data;
68};
69
70class JSONNumber : public JSONValue {
71public:
72 typedef std::shared_ptr<JSONNumber> SP;
73
74 // We cretae a constructor for all integer and floating point type with using
75 // templates and
76 // SFINAE to avoid having ambiguous overloads because of the implicit type
77 // promotion. If we
78 // would have constructors only with int64_t, uint64_t and double types then
79 // constructing a JSONNumber from an int32_t (or any other similar type)
80 // would fail to compile.
81
82 template <typename T, typename std::enable_if<
83 std::is_integral<T>::value &&
84 std::is_unsigned<T>::value>::type * = nullptr>
85 explicit JSONNumber(T u)
86 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
87 m_data.m_unsigned = u;
88 }
89
90 template <typename T,
91 typename std::enable_if<std::is_integral<T>::value &&
92 std::is_signed<T>::value>::type * = nullptr>
93 explicit JSONNumber(T s)
94 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
95 m_data.m_signed = s;
96 }
97
98 template <typename T, typename std::enable_if<
99 std::is_floating_point<T>::value>::type * = nullptr>
100 explicit JSONNumber(T d)
101 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
102 m_data.m_double = d;
103 }
104
105 ~JSONNumber() override = default;
106
107 JSONNumber(const JSONNumber &s) = delete;
108 JSONNumber &operator=(const JSONNumber &s) = delete;
109
110 void Write(Stream &s) override;
111
112 uint64_t GetAsUnsigned() const;
113
114 int64_t GetAsSigned() const;
115
116 double GetAsDouble() const;
117
118 static bool classof(const JSONValue *V) {
119 return V->GetKind() == JSONValue::Kind::Number;
120 }
121
122private:
123 enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
124
125 union {
126 uint64_t m_unsigned;
127 int64_t m_signed;
128 double m_double;
129 } m_data;
130};
131
132class JSONTrue : public JSONValue {
133public:
134 JSONTrue();
135
136 JSONTrue(const JSONTrue &s) = delete;
137 JSONTrue &operator=(const JSONTrue &s) = delete;
138
139 void Write(Stream &s) override;
140
141 typedef std::shared_ptr<JSONTrue> SP;
142
143 static bool classof(const JSONValue *V) {
144 return V->GetKind() == JSONValue::Kind::True;
145 }
146
147 ~JSONTrue() override = default;
148};
149
150class JSONFalse : public JSONValue {
151public:
152 JSONFalse();
153
154 JSONFalse(const JSONFalse &s) = delete;
155 JSONFalse &operator=(const JSONFalse &s) = delete;
156
157 void Write(Stream &s) override;
158
159 typedef std::shared_ptr<JSONFalse> SP;
160
161 static bool classof(const JSONValue *V) {
162 return V->GetKind() == JSONValue::Kind::False;
163 }
164
165 ~JSONFalse() override = default;
166};
167
168class JSONNull : public JSONValue {
169public:
170 JSONNull();
171
172 JSONNull(const JSONNull &s) = delete;
173 JSONNull &operator=(const JSONNull &s) = delete;
174
175 void Write(Stream &s) override;
176
177 typedef std::shared_ptr<JSONNull> SP;
178
179 static bool classof(const JSONValue *V) {
180 return V->GetKind() == JSONValue::Kind::Null;
181 }
182
183 ~JSONNull() override = default;
184};
185
186class JSONObject : public JSONValue {
187public:
188 JSONObject();
189
190 JSONObject(const JSONObject &s) = delete;
191 JSONObject &operator=(const JSONObject &s) = delete;
192
193 void Write(Stream &s) override;
194
195 typedef std::shared_ptr<JSONObject> SP;
196
197 static bool classof(const JSONValue *V) {
198 return V->GetKind() == JSONValue::Kind::Object;
199 }
200
201 bool SetObject(const std::string &key, JSONValue::SP value);
202
203 JSONValue::SP GetObject(const std::string &key);
204
205 ~JSONObject() override = default;
206
207private:
208 typedef std::map<std::string, JSONValue::SP> Map;
209 typedef Map::iterator Iterator;
210 Map m_elements;
211};
212
213class JSONArray : public JSONValue {
214public:
215 JSONArray();
216
217 JSONArray(const JSONArray &s) = delete;
218 JSONArray &operator=(const JSONArray &s) = delete;
219
220 void Write(Stream &s) override;
221
222 typedef std::shared_ptr<JSONArray> SP;
223
224 static bool classof(const JSONValue *V) {
225 return V->GetKind() == JSONValue::Kind::Array;
226 }
227
228private:
229 typedef std::vector<JSONValue::SP> Vector;
230 typedef Vector::iterator Iterator;
231 typedef Vector::size_type Index;
232 typedef Vector::size_type Size;
233
234public:
235 bool SetObject(Index i, JSONValue::SP value);
236
237 bool AppendObject(JSONValue::SP value);
238
239 JSONValue::SP GetObject(Index i);
240
241 Size GetNumElements();
242
243 ~JSONArray() override = default;
244
245 Vector m_elements;
246};
247
248class JSONParser : public StringExtractor {
249public:
250 enum Token {
251 Invalid,
252 Status,
253 ObjectStart,
254 ObjectEnd,
255 ArrayStart,
256 ArrayEnd,
257 Comma,
258 Colon,
259 String,
260 Integer,
261 Float,
262 True,
263 False,
264 Null,
265 EndOfFile
266 };
267
268 JSONParser(llvm::StringRef data);
269
270 int GetEscapedChar(bool &was_escaped);
271
272 Token GetToken(std::string &value);
273
274 JSONValue::SP ParseJSONValue();
275
276protected:
277 JSONValue::SP ParseJSONObject();
278
279 JSONValue::SP ParseJSONArray();
280};
281} // namespace lldb_private
282
283#endif // utility_JSON_h_