• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- JSON.h - JSON values, parsing and serialization -------*- 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 /// \file
10 /// This file supports working with JSON data.
11 ///
12 /// It comprises:
13 ///
14 /// - classes which hold dynamically-typed parsed JSON structures
15 ///   These are value types that can be composed, inspected, and modified.
16 ///   See json::Value, and the related types json::Object and json::Array.
17 ///
18 /// - functions to parse JSON text into Values, and to serialize Values to text.
19 ///   See parse(), operator<<, and format_provider.
20 ///
21 /// - a convention and helpers for mapping between json::Value and user-defined
22 ///   types. See fromJSON(), ObjectMapper, and the class comment on Value.
23 ///
24 /// - an output API json::OStream which can emit JSON without materializing
25 ///   all structures as json::Value.
26 ///
27 /// Typically, JSON data would be read from an external source, parsed into
28 /// a Value, and then converted into some native data structure before doing
29 /// real work on it. (And vice versa when writing).
30 ///
31 /// Other serialization mechanisms you may consider:
32 ///
33 /// - YAML is also text-based, and more human-readable than JSON. It's a more
34 ///   complex format and data model, and YAML parsers aren't ubiquitous.
35 ///   YAMLParser.h is a streaming parser suitable for parsing large documents
36 ///   (including JSON, as YAML is a superset). It can be awkward to use
37 ///   directly. YAML I/O (YAMLTraits.h) provides data mapping that is more
38 ///   declarative than the toJSON/fromJSON conventions here.
39 ///
40 /// - LLVM bitstream is a space- and CPU- efficient binary format. Typically it
41 ///   encodes LLVM IR ("bitcode"), but it can be a container for other data.
42 ///   Low-level reader/writer libraries are in Bitstream/Bitstream*.h
43 ///
44 //===---------------------------------------------------------------------===//
45 
46 #ifndef LLVM_SUPPORT_JSON_H
47 #define LLVM_SUPPORT_JSON_H
48 
49 #include "llvm/ADT/DenseMap.h"
50 #include "llvm/ADT/SmallVector.h"
51 #include "llvm/ADT/StringRef.h"
52 #include "llvm/Support/Error.h"
53 #include "llvm/Support/FormatVariadic.h"
54 #include "llvm/Support/raw_ostream.h"
55 #include <map>
56 
57 namespace llvm {
58 namespace json {
59 
60 // === String encodings ===
61 //
62 // JSON strings are character sequences (not byte sequences like std::string).
63 // We need to know the encoding, and for simplicity only support UTF-8.
64 //
65 //   - When parsing, invalid UTF-8 is a syntax error like any other
66 //
67 //   - When creating Values from strings, callers must ensure they are UTF-8.
68 //        with asserts on, invalid UTF-8 will crash the program
69 //        with asserts off, we'll substitute the replacement character (U+FFFD)
70 //     Callers can use json::isUTF8() and json::fixUTF8() for validation.
71 //
72 //   - When retrieving strings from Values (e.g. asString()), the result will
73 //     always be valid UTF-8.
74 
75 /// Returns true if \p S is valid UTF-8, which is required for use as JSON.
76 /// If it returns false, \p Offset is set to a byte offset near the first error.
77 bool isUTF8(llvm::StringRef S, size_t *ErrOffset = nullptr);
78 /// Replaces invalid UTF-8 sequences in \p S with the replacement character
79 /// (U+FFFD). The returned string is valid UTF-8.
80 /// This is much slower than isUTF8, so test that first.
81 std::string fixUTF8(llvm::StringRef S);
82 
83 class Array;
84 class ObjectKey;
85 class Value;
86 template <typename T> Value toJSON(const llvm::Optional<T> &Opt);
87 
88 /// An Object is a JSON object, which maps strings to heterogenous JSON values.
89 /// It simulates DenseMap<ObjectKey, Value>. ObjectKey is a maybe-owned string.
90 class Object {
91   using Storage = DenseMap<ObjectKey, Value, llvm::DenseMapInfo<StringRef>>;
92   Storage M;
93 
94 public:
95   using key_type = ObjectKey;
96   using mapped_type = Value;
97   using value_type = Storage::value_type;
98   using iterator = Storage::iterator;
99   using const_iterator = Storage::const_iterator;
100 
101   Object() = default;
102   // KV is a trivial key-value struct for list-initialization.
103   // (using std::pair forces extra copies).
104   struct KV;
105   explicit Object(std::initializer_list<KV> Properties);
106 
begin()107   iterator begin() { return M.begin(); }
begin()108   const_iterator begin() const { return M.begin(); }
end()109   iterator end() { return M.end(); }
end()110   const_iterator end() const { return M.end(); }
111 
empty()112   bool empty() const { return M.empty(); }
size()113   size_t size() const { return M.size(); }
114 
clear()115   void clear() { M.clear(); }
116   std::pair<iterator, bool> insert(KV E);
117   template <typename... Ts>
try_emplace(const ObjectKey & K,Ts &&...Args)118   std::pair<iterator, bool> try_emplace(const ObjectKey &K, Ts &&... Args) {
119     return M.try_emplace(K, std::forward<Ts>(Args)...);
120   }
121   template <typename... Ts>
try_emplace(ObjectKey && K,Ts &&...Args)122   std::pair<iterator, bool> try_emplace(ObjectKey &&K, Ts &&... Args) {
123     return M.try_emplace(std::move(K), std::forward<Ts>(Args)...);
124   }
125   bool erase(StringRef K);
erase(iterator I)126   void erase(iterator I) { M.erase(I); }
127 
find(StringRef K)128   iterator find(StringRef K) { return M.find_as(K); }
find(StringRef K)129   const_iterator find(StringRef K) const { return M.find_as(K); }
130   // operator[] acts as if Value was default-constructible as null.
131   Value &operator[](const ObjectKey &K);
132   Value &operator[](ObjectKey &&K);
133   // Look up a property, returning nullptr if it doesn't exist.
134   Value *get(StringRef K);
135   const Value *get(StringRef K) const;
136   // Typed accessors return None/nullptr if
137   //   - the property doesn't exist
138   //   - or it has the wrong type
139   llvm::Optional<std::nullptr_t> getNull(StringRef K) const;
140   llvm::Optional<bool> getBoolean(StringRef K) const;
141   llvm::Optional<double> getNumber(StringRef K) const;
142   llvm::Optional<int64_t> getInteger(StringRef K) const;
143   llvm::Optional<llvm::StringRef> getString(StringRef K) const;
144   const json::Object *getObject(StringRef K) const;
145   json::Object *getObject(StringRef K);
146   const json::Array *getArray(StringRef K) const;
147   json::Array *getArray(StringRef K);
148 };
149 bool operator==(const Object &LHS, const Object &RHS);
150 inline bool operator!=(const Object &LHS, const Object &RHS) {
151   return !(LHS == RHS);
152 }
153 
154 /// An Array is a JSON array, which contains heterogeneous JSON values.
155 /// It simulates std::vector<Value>.
156 class Array {
157   std::vector<Value> V;
158 
159 public:
160   using value_type = Value;
161   using iterator = std::vector<Value>::iterator;
162   using const_iterator = std::vector<Value>::const_iterator;
163 
164   Array() = default;
165   explicit Array(std::initializer_list<Value> Elements);
Array(const Collection & C)166   template <typename Collection> explicit Array(const Collection &C) {
167     for (const auto &V : C)
168       emplace_back(V);
169   }
170 
171   Value &operator[](size_t I);
172   const Value &operator[](size_t I) const;
173   Value &front();
174   const Value &front() const;
175   Value &back();
176   const Value &back() const;
177   Value *data();
178   const Value *data() const;
179 
180   iterator begin();
181   const_iterator begin() const;
182   iterator end();
183   const_iterator end() const;
184 
185   bool empty() const;
186   size_t size() const;
187   void reserve(size_t S);
188 
189   void clear();
190   void push_back(const Value &E);
191   void push_back(Value &&E);
192   template <typename... Args> void emplace_back(Args &&...A);
193   void pop_back();
194   // FIXME: insert() takes const_iterator since C++11, old libstdc++ disagrees.
195   iterator insert(iterator P, const Value &E);
196   iterator insert(iterator P, Value &&E);
197   template <typename It> iterator insert(iterator P, It A, It Z);
198   template <typename... Args> iterator emplace(const_iterator P, Args &&...A);
199 
200   friend bool operator==(const Array &L, const Array &R);
201 };
202 inline bool operator!=(const Array &L, const Array &R) { return !(L == R); }
203 
204 /// A Value is an JSON value of unknown type.
205 /// They can be copied, but should generally be moved.
206 ///
207 /// === Composing values ===
208 ///
209 /// You can implicitly construct Values from:
210 ///   - strings: std::string, SmallString, formatv, StringRef, char*
211 ///              (char*, and StringRef are references, not copies!)
212 ///   - numbers
213 ///   - booleans
214 ///   - null: nullptr
215 ///   - arrays: {"foo", 42.0, false}
216 ///   - serializable things: types with toJSON(const T&)->Value, found by ADL
217 ///
218 /// They can also be constructed from object/array helpers:
219 ///   - json::Object is a type like map<ObjectKey, Value>
220 ///   - json::Array is a type like vector<Value>
221 /// These can be list-initialized, or used to build up collections in a loop.
222 /// json::ary(Collection) converts all items in a collection to Values.
223 ///
224 /// === Inspecting values ===
225 ///
226 /// Each Value is one of the JSON kinds:
227 ///   null    (nullptr_t)
228 ///   boolean (bool)
229 ///   number  (double or int64)
230 ///   string  (StringRef)
231 ///   array   (json::Array)
232 ///   object  (json::Object)
233 ///
234 /// The kind can be queried directly, or implicitly via the typed accessors:
235 ///   if (Optional<StringRef> S = E.getAsString()
236 ///     assert(E.kind() == Value::String);
237 ///
238 /// Array and Object also have typed indexing accessors for easy traversal:
239 ///   Expected<Value> E = parse(R"( {"options": {"font": "sans-serif"}} )");
240 ///   if (Object* O = E->getAsObject())
241 ///     if (Object* Opts = O->getObject("options"))
242 ///       if (Optional<StringRef> Font = Opts->getString("font"))
243 ///         assert(Opts->at("font").kind() == Value::String);
244 ///
245 /// === Converting JSON values to C++ types ===
246 ///
247 /// The convention is to have a deserializer function findable via ADL:
248 ///     fromJSON(const json::Value&, T&)->bool
249 /// Deserializers are provided for:
250 ///   - bool
251 ///   - int and int64_t
252 ///   - double
253 ///   - std::string
254 ///   - vector<T>, where T is deserializable
255 ///   - map<string, T>, where T is deserializable
256 ///   - Optional<T>, where T is deserializable
257 /// ObjectMapper can help writing fromJSON() functions for object types.
258 ///
259 /// For conversion in the other direction, the serializer function is:
260 ///    toJSON(const T&) -> json::Value
261 /// If this exists, then it also allows constructing Value from T, and can
262 /// be used to serialize vector<T>, map<string, T>, and Optional<T>.
263 ///
264 /// === Serialization ===
265 ///
266 /// Values can be serialized to JSON:
267 ///   1) raw_ostream << Value                    // Basic formatting.
268 ///   2) raw_ostream << formatv("{0}", Value)    // Basic formatting.
269 ///   3) raw_ostream << formatv("{0:2}", Value)  // Pretty-print with indent 2.
270 ///
271 /// And parsed:
272 ///   Expected<Value> E = json::parse("[1, 2, null]");
273 ///   assert(E && E->kind() == Value::Array);
274 class Value {
275 public:
276   enum Kind {
277     Null,
278     Boolean,
279     /// Number values can store both int64s and doubles at full precision,
280     /// depending on what they were constructed/parsed from.
281     Number,
282     String,
283     Array,
284     Object,
285   };
286 
287   // It would be nice to have Value() be null. But that would make {} null too.
Value(const Value & M)288   Value(const Value &M) { copyFrom(M); }
Value(Value && M)289   Value(Value &&M) { moveFrom(std::move(M)); }
290   Value(std::initializer_list<Value> Elements);
Value(json::Array && Elements)291   Value(json::Array &&Elements) : Type(T_Array) {
292     create<json::Array>(std::move(Elements));
293   }
294   template <typename Elt>
Value(const std::vector<Elt> & C)295   Value(const std::vector<Elt> &C) : Value(json::Array(C)) {}
Value(json::Object && Properties)296   Value(json::Object &&Properties) : Type(T_Object) {
297     create<json::Object>(std::move(Properties));
298   }
299   template <typename Elt>
Value(const std::map<std::string,Elt> & C)300   Value(const std::map<std::string, Elt> &C) : Value(json::Object(C)) {}
301   // Strings: types with value semantics. Must be valid UTF-8.
Value(std::string V)302   Value(std::string V) : Type(T_String) {
303     if (LLVM_UNLIKELY(!isUTF8(V))) {
304       assert(false && "Invalid UTF-8 in value used as JSON");
305       V = fixUTF8(std::move(V));
306     }
307     create<std::string>(std::move(V));
308   }
Value(const llvm::SmallVectorImpl<char> & V)309   Value(const llvm::SmallVectorImpl<char> &V)
310       : Value(std::string(V.begin(), V.end())) {}
Value(const llvm::formatv_object_base & V)311   Value(const llvm::formatv_object_base &V) : Value(V.str()) {}
312   // Strings: types with reference semantics. Must be valid UTF-8.
Value(StringRef V)313   Value(StringRef V) : Type(T_StringRef) {
314     create<llvm::StringRef>(V);
315     if (LLVM_UNLIKELY(!isUTF8(V))) {
316       assert(false && "Invalid UTF-8 in value used as JSON");
317       *this = Value(fixUTF8(V));
318     }
319   }
Value(const char * V)320   Value(const char *V) : Value(StringRef(V)) {}
Value(std::nullptr_t)321   Value(std::nullptr_t) : Type(T_Null) {}
322   // Boolean (disallow implicit conversions).
323   // (The last template parameter is a dummy to keep templates distinct.)
324   template <
325       typename T,
326       typename = typename std::enable_if<std::is_same<T, bool>::value>::type,
327       bool = false>
Value(T B)328   Value(T B) : Type(T_Boolean) {
329     create<bool>(B);
330   }
331   // Integers (except boolean). Must be non-narrowing convertible to int64_t.
332   template <
333       typename T,
334       typename = typename std::enable_if<std::is_integral<T>::value>::type,
335       typename = typename std::enable_if<!std::is_same<T, bool>::value>::type>
Value(T I)336   Value(T I) : Type(T_Integer) {
337     create<int64_t>(int64_t{I});
338   }
339   // Floating point. Must be non-narrowing convertible to double.
340   template <typename T,
341             typename =
342                 typename std::enable_if<std::is_floating_point<T>::value>::type,
343             double * = nullptr>
Value(T D)344   Value(T D) : Type(T_Double) {
345     create<double>(double{D});
346   }
347   // Serializable types: with a toJSON(const T&)->Value function, found by ADL.
348   template <typename T,
349             typename = typename std::enable_if<std::is_same<
350                 Value, decltype(toJSON(*(const T *)nullptr))>::value>,
351             Value * = nullptr>
Value(const T & V)352   Value(const T &V) : Value(toJSON(V)) {}
353 
354   Value &operator=(const Value &M) {
355     destroy();
356     copyFrom(M);
357     return *this;
358   }
359   Value &operator=(Value &&M) {
360     destroy();
361     moveFrom(std::move(M));
362     return *this;
363   }
~Value()364   ~Value() { destroy(); }
365 
kind()366   Kind kind() const {
367     switch (Type) {
368     case T_Null:
369       return Null;
370     case T_Boolean:
371       return Boolean;
372     case T_Double:
373     case T_Integer:
374       return Number;
375     case T_String:
376     case T_StringRef:
377       return String;
378     case T_Object:
379       return Object;
380     case T_Array:
381       return Array;
382     }
383     llvm_unreachable("Unknown kind");
384   }
385 
386   // Typed accessors return None/nullptr if the Value is not of this type.
getAsNull()387   llvm::Optional<std::nullptr_t> getAsNull() const {
388     if (LLVM_LIKELY(Type == T_Null))
389       return nullptr;
390     return llvm::None;
391   }
getAsBoolean()392   llvm::Optional<bool> getAsBoolean() const {
393     if (LLVM_LIKELY(Type == T_Boolean))
394       return as<bool>();
395     return llvm::None;
396   }
getAsNumber()397   llvm::Optional<double> getAsNumber() const {
398     if (LLVM_LIKELY(Type == T_Double))
399       return as<double>();
400     if (LLVM_LIKELY(Type == T_Integer))
401       return as<int64_t>();
402     return llvm::None;
403   }
404   // Succeeds if the Value is a Number, and exactly representable as int64_t.
getAsInteger()405   llvm::Optional<int64_t> getAsInteger() const {
406     if (LLVM_LIKELY(Type == T_Integer))
407       return as<int64_t>();
408     if (LLVM_LIKELY(Type == T_Double)) {
409       double D = as<double>();
410       if (LLVM_LIKELY(std::modf(D, &D) == 0.0 &&
411                       D >= double(std::numeric_limits<int64_t>::min()) &&
412                       D <= double(std::numeric_limits<int64_t>::max())))
413         return D;
414     }
415     return llvm::None;
416   }
getAsString()417   llvm::Optional<llvm::StringRef> getAsString() const {
418     if (Type == T_String)
419       return llvm::StringRef(as<std::string>());
420     if (LLVM_LIKELY(Type == T_StringRef))
421       return as<llvm::StringRef>();
422     return llvm::None;
423   }
getAsObject()424   const json::Object *getAsObject() const {
425     return LLVM_LIKELY(Type == T_Object) ? &as<json::Object>() : nullptr;
426   }
getAsObject()427   json::Object *getAsObject() {
428     return LLVM_LIKELY(Type == T_Object) ? &as<json::Object>() : nullptr;
429   }
getAsArray()430   const json::Array *getAsArray() const {
431     return LLVM_LIKELY(Type == T_Array) ? &as<json::Array>() : nullptr;
432   }
getAsArray()433   json::Array *getAsArray() {
434     return LLVM_LIKELY(Type == T_Array) ? &as<json::Array>() : nullptr;
435   }
436 
437 private:
438   void destroy();
439   void copyFrom(const Value &M);
440   // We allow moving from *const* Values, by marking all members as mutable!
441   // This hack is needed to support initializer-list syntax efficiently.
442   // (std::initializer_list<T> is a container of const T).
443   void moveFrom(const Value &&M);
444   friend class Array;
445   friend class Object;
446 
create(U &&...V)447   template <typename T, typename... U> void create(U &&... V) {
448     new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
449   }
as()450   template <typename T> T &as() const {
451     // Using this two-step static_cast via void * instead of reinterpret_cast
452     // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
453     void *Storage = static_cast<void *>(Union.buffer);
454     return *static_cast<T *>(Storage);
455   }
456 
457   friend class OStream;
458 
459   enum ValueType : char {
460     T_Null,
461     T_Boolean,
462     T_Double,
463     T_Integer,
464     T_StringRef,
465     T_String,
466     T_Object,
467     T_Array,
468   };
469   // All members mutable, see moveFrom().
470   mutable ValueType Type;
471   mutable llvm::AlignedCharArrayUnion<bool, double, int64_t, llvm::StringRef,
472                                       std::string, json::Array, json::Object>
473       Union;
474   friend bool operator==(const Value &, const Value &);
475 };
476 
477 bool operator==(const Value &, const Value &);
478 inline bool operator!=(const Value &L, const Value &R) { return !(L == R); }
479 
480 // Array Methods
481 inline Value &Array::operator[](size_t I) { return V[I]; }
482 inline const Value &Array::operator[](size_t I) const { return V[I]; }
front()483 inline Value &Array::front() { return V.front(); }
front()484 inline const Value &Array::front() const { return V.front(); }
back()485 inline Value &Array::back() { return V.back(); }
back()486 inline const Value &Array::back() const { return V.back(); }
data()487 inline Value *Array::data() { return V.data(); }
data()488 inline const Value *Array::data() const { return V.data(); }
489 
begin()490 inline typename Array::iterator Array::begin() { return V.begin(); }
begin()491 inline typename Array::const_iterator Array::begin() const { return V.begin(); }
end()492 inline typename Array::iterator Array::end() { return V.end(); }
end()493 inline typename Array::const_iterator Array::end() const { return V.end(); }
494 
empty()495 inline bool Array::empty() const { return V.empty(); }
size()496 inline size_t Array::size() const { return V.size(); }
reserve(size_t S)497 inline void Array::reserve(size_t S) { V.reserve(S); }
498 
clear()499 inline void Array::clear() { V.clear(); }
push_back(const Value & E)500 inline void Array::push_back(const Value &E) { V.push_back(E); }
push_back(Value && E)501 inline void Array::push_back(Value &&E) { V.push_back(std::move(E)); }
emplace_back(Args &&...A)502 template <typename... Args> inline void Array::emplace_back(Args &&...A) {
503   V.emplace_back(std::forward<Args>(A)...);
504 }
pop_back()505 inline void Array::pop_back() { V.pop_back(); }
insert(iterator P,const Value & E)506 inline typename Array::iterator Array::insert(iterator P, const Value &E) {
507   return V.insert(P, E);
508 }
insert(iterator P,Value && E)509 inline typename Array::iterator Array::insert(iterator P, Value &&E) {
510   return V.insert(P, std::move(E));
511 }
512 template <typename It>
insert(iterator P,It A,It Z)513 inline typename Array::iterator Array::insert(iterator P, It A, It Z) {
514   return V.insert(P, A, Z);
515 }
516 template <typename... Args>
emplace(const_iterator P,Args &&...A)517 inline typename Array::iterator Array::emplace(const_iterator P, Args &&...A) {
518   return V.emplace(P, std::forward<Args>(A)...);
519 }
520 inline bool operator==(const Array &L, const Array &R) { return L.V == R.V; }
521 
522 /// ObjectKey is a used to capture keys in Object. Like Value but:
523 ///   - only strings are allowed
524 ///   - it's optimized for the string literal case (Owned == nullptr)
525 /// Like Value, strings must be UTF-8. See isUTF8 documentation for details.
526 class ObjectKey {
527 public:
ObjectKey(const char * S)528   ObjectKey(const char *S) : ObjectKey(StringRef(S)) {}
ObjectKey(std::string S)529   ObjectKey(std::string S) : Owned(new std::string(std::move(S))) {
530     if (LLVM_UNLIKELY(!isUTF8(*Owned))) {
531       assert(false && "Invalid UTF-8 in value used as JSON");
532       *Owned = fixUTF8(std::move(*Owned));
533     }
534     Data = *Owned;
535   }
ObjectKey(llvm::StringRef S)536   ObjectKey(llvm::StringRef S) : Data(S) {
537     if (LLVM_UNLIKELY(!isUTF8(Data))) {
538       assert(false && "Invalid UTF-8 in value used as JSON");
539       *this = ObjectKey(fixUTF8(S));
540     }
541   }
ObjectKey(const llvm::SmallVectorImpl<char> & V)542   ObjectKey(const llvm::SmallVectorImpl<char> &V)
543       : ObjectKey(std::string(V.begin(), V.end())) {}
ObjectKey(const llvm::formatv_object_base & V)544   ObjectKey(const llvm::formatv_object_base &V) : ObjectKey(V.str()) {}
545 
ObjectKey(const ObjectKey & C)546   ObjectKey(const ObjectKey &C) { *this = C; }
ObjectKey(ObjectKey && C)547   ObjectKey(ObjectKey &&C) : ObjectKey(static_cast<const ObjectKey &&>(C)) {}
548   ObjectKey &operator=(const ObjectKey &C) {
549     if (C.Owned) {
550       Owned.reset(new std::string(*C.Owned));
551       Data = *Owned;
552     } else {
553       Data = C.Data;
554     }
555     return *this;
556   }
557   ObjectKey &operator=(ObjectKey &&) = default;
558 
StringRef()559   operator llvm::StringRef() const { return Data; }
str()560   std::string str() const { return Data.str(); }
561 
562 private:
563   // FIXME: this is unneccesarily large (3 pointers). Pointer + length + owned
564   // could be 2 pointers at most.
565   std::unique_ptr<std::string> Owned;
566   llvm::StringRef Data;
567 };
568 
569 inline bool operator==(const ObjectKey &L, const ObjectKey &R) {
570   return llvm::StringRef(L) == llvm::StringRef(R);
571 }
572 inline bool operator!=(const ObjectKey &L, const ObjectKey &R) {
573   return !(L == R);
574 }
575 inline bool operator<(const ObjectKey &L, const ObjectKey &R) {
576   return StringRef(L) < StringRef(R);
577 }
578 
579 struct Object::KV {
580   ObjectKey K;
581   Value V;
582 };
583 
Object(std::initializer_list<KV> Properties)584 inline Object::Object(std::initializer_list<KV> Properties) {
585   for (const auto &P : Properties) {
586     auto R = try_emplace(P.K, nullptr);
587     if (R.second)
588       R.first->getSecond().moveFrom(std::move(P.V));
589   }
590 }
insert(KV E)591 inline std::pair<Object::iterator, bool> Object::insert(KV E) {
592   return try_emplace(std::move(E.K), std::move(E.V));
593 }
erase(StringRef K)594 inline bool Object::erase(StringRef K) {
595   return M.erase(ObjectKey(K));
596 }
597 
598 // Standard deserializers are provided for primitive types.
599 // See comments on Value.
fromJSON(const Value & E,std::string & Out)600 inline bool fromJSON(const Value &E, std::string &Out) {
601   if (auto S = E.getAsString()) {
602     Out = *S;
603     return true;
604   }
605   return false;
606 }
fromJSON(const Value & E,int & Out)607 inline bool fromJSON(const Value &E, int &Out) {
608   if (auto S = E.getAsInteger()) {
609     Out = *S;
610     return true;
611   }
612   return false;
613 }
fromJSON(const Value & E,int64_t & Out)614 inline bool fromJSON(const Value &E, int64_t &Out) {
615   if (auto S = E.getAsInteger()) {
616     Out = *S;
617     return true;
618   }
619   return false;
620 }
fromJSON(const Value & E,double & Out)621 inline bool fromJSON(const Value &E, double &Out) {
622   if (auto S = E.getAsNumber()) {
623     Out = *S;
624     return true;
625   }
626   return false;
627 }
fromJSON(const Value & E,bool & Out)628 inline bool fromJSON(const Value &E, bool &Out) {
629   if (auto S = E.getAsBoolean()) {
630     Out = *S;
631     return true;
632   }
633   return false;
634 }
fromJSON(const Value & E,llvm::Optional<T> & Out)635 template <typename T> bool fromJSON(const Value &E, llvm::Optional<T> &Out) {
636   if (E.getAsNull()) {
637     Out = llvm::None;
638     return true;
639   }
640   T Result;
641   if (!fromJSON(E, Result))
642     return false;
643   Out = std::move(Result);
644   return true;
645 }
fromJSON(const Value & E,std::vector<T> & Out)646 template <typename T> bool fromJSON(const Value &E, std::vector<T> &Out) {
647   if (auto *A = E.getAsArray()) {
648     Out.clear();
649     Out.resize(A->size());
650     for (size_t I = 0; I < A->size(); ++I)
651       if (!fromJSON((*A)[I], Out[I]))
652         return false;
653     return true;
654   }
655   return false;
656 }
657 template <typename T>
fromJSON(const Value & E,std::map<std::string,T> & Out)658 bool fromJSON(const Value &E, std::map<std::string, T> &Out) {
659   if (auto *O = E.getAsObject()) {
660     Out.clear();
661     for (const auto &KV : *O)
662       if (!fromJSON(KV.second, Out[llvm::StringRef(KV.first)]))
663         return false;
664     return true;
665   }
666   return false;
667 }
668 
669 // Allow serialization of Optional<T> for supported T.
toJSON(const llvm::Optional<T> & Opt)670 template <typename T> Value toJSON(const llvm::Optional<T> &Opt) {
671   return Opt ? Value(*Opt) : Value(nullptr);
672 }
673 
674 /// Helper for mapping JSON objects onto protocol structs.
675 ///
676 /// Example:
677 /// \code
678 ///   bool fromJSON(const Value &E, MyStruct &R) {
679 ///     ObjectMapper O(E);
680 ///     if (!O || !O.map("mandatory_field", R.MandatoryField))
681 ///       return false;
682 ///     O.map("optional_field", R.OptionalField);
683 ///     return true;
684 ///   }
685 /// \endcode
686 class ObjectMapper {
687 public:
ObjectMapper(const Value & E)688   ObjectMapper(const Value &E) : O(E.getAsObject()) {}
689 
690   /// True if the expression is an object.
691   /// Must be checked before calling map().
692   operator bool() { return O; }
693 
694   /// Maps a property to a field, if it exists.
map(StringRef Prop,T & Out)695   template <typename T> bool map(StringRef Prop, T &Out) {
696     assert(*this && "Must check this is an object before calling map()");
697     if (const Value *E = O->get(Prop))
698       return fromJSON(*E, Out);
699     return false;
700   }
701 
702   /// Maps a property to a field, if it exists.
703   /// (Optional requires special handling, because missing keys are OK).
map(StringRef Prop,llvm::Optional<T> & Out)704   template <typename T> bool map(StringRef Prop, llvm::Optional<T> &Out) {
705     assert(*this && "Must check this is an object before calling map()");
706     if (const Value *E = O->get(Prop))
707       return fromJSON(*E, Out);
708     Out = llvm::None;
709     return true;
710   }
711 
712 private:
713   const Object *O;
714 };
715 
716 /// Parses the provided JSON source, or returns a ParseError.
717 /// The returned Value is self-contained and owns its strings (they do not refer
718 /// to the original source).
719 llvm::Expected<Value> parse(llvm::StringRef JSON);
720 
721 class ParseError : public llvm::ErrorInfo<ParseError> {
722   const char *Msg;
723   unsigned Line, Column, Offset;
724 
725 public:
726   static char ID;
ParseError(const char * Msg,unsigned Line,unsigned Column,unsigned Offset)727   ParseError(const char *Msg, unsigned Line, unsigned Column, unsigned Offset)
728       : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
log(llvm::raw_ostream & OS)729   void log(llvm::raw_ostream &OS) const override {
730     OS << llvm::formatv("[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
731   }
convertToErrorCode()732   std::error_code convertToErrorCode() const override {
733     return llvm::inconvertibleErrorCode();
734   }
735 };
736 
737 /// json::OStream allows writing well-formed JSON without materializing
738 /// all structures as json::Value ahead of time.
739 /// It's faster, lower-level, and less safe than OS << json::Value.
740 ///
741 /// Only one "top-level" object can be written to a stream.
742 /// Simplest usage involves passing lambdas (Blocks) to fill in containers:
743 ///
744 ///   json::OStream J(OS);
745 ///   J.array([&]{
746 ///     for (const Event &E : Events)
747 ///       J.object([&] {
748 ///         J.attribute("timestamp", int64_t(E.Time));
749 ///         J.attributeArray("participants", [&] {
750 ///           for (const Participant &P : E.Participants)
751 ///             J.value(P.toString());
752 ///         });
753 ///       });
754 ///   });
755 ///
756 /// This would produce JSON like:
757 ///
758 ///   [
759 ///     {
760 ///       "timestamp": 19287398741,
761 ///       "participants": [
762 ///         "King Kong",
763 ///         "Miley Cyrus",
764 ///         "Cleopatra"
765 ///       ]
766 ///     },
767 ///     ...
768 ///   ]
769 ///
770 /// The lower level begin/end methods (arrayBegin()) are more flexible but
771 /// care must be taken to pair them correctly:
772 ///
773 ///   json::OStream J(OS);
774 //    J.arrayBegin();
775 ///   for (const Event &E : Events) {
776 ///     J.objectBegin();
777 ///     J.attribute("timestamp", int64_t(E.Time));
778 ///     J.attributeBegin("participants");
779 ///     for (const Participant &P : E.Participants)
780 ///       J.value(P.toString());
781 ///     J.attributeEnd();
782 ///     J.objectEnd();
783 ///   }
784 ///   J.arrayEnd();
785 ///
786 /// If the call sequence isn't valid JSON, asserts will fire in debug mode.
787 /// This can be mismatched begin()/end() pairs, trying to emit attributes inside
788 /// an array, and so on.
789 /// With asserts disabled, this is undefined behavior.
790 class OStream {
791  public:
792   using Block = llvm::function_ref<void()>;
793   // If IndentSize is nonzero, output is pretty-printed.
794   explicit OStream(llvm::raw_ostream &OS, unsigned IndentSize = 0)
OS(OS)795       : OS(OS), IndentSize(IndentSize) {
796     Stack.emplace_back();
797   }
~OStream()798   ~OStream() {
799     assert(Stack.size() == 1 && "Unmatched begin()/end()");
800     assert(Stack.back().Ctx == Singleton);
801     assert(Stack.back().HasValue && "Did not write top-level value");
802   }
803 
804   /// Flushes the underlying ostream. OStream does not buffer internally.
flush()805   void flush() { OS.flush(); }
806 
807   // High level functions to output a value.
808   // Valid at top-level (exactly once), in an attribute value (exactly once),
809   // or in an array (any number of times).
810 
811   /// Emit a self-contained value (number, string, vector<string> etc).
812   void value(const Value &V);
813   /// Emit an array whose elements are emitted in the provided Block.
array(Block Contents)814   void array(Block Contents) {
815     arrayBegin();
816     Contents();
817     arrayEnd();
818   }
819   /// Emit an object whose elements are emitted in the provided Block.
object(Block Contents)820   void object(Block Contents) {
821     objectBegin();
822     Contents();
823     objectEnd();
824   }
825 
826   // High level functions to output object attributes.
827   // Valid only within an object (any number of times).
828 
829   /// Emit an attribute whose value is self-contained (number, vector<int> etc).
attribute(llvm::StringRef Key,const Value & Contents)830   void attribute(llvm::StringRef Key, const Value& Contents) {
831     attributeImpl(Key, [&] { value(Contents); });
832   }
833   /// Emit an attribute whose value is an array with elements from the Block.
attributeArray(llvm::StringRef Key,Block Contents)834   void attributeArray(llvm::StringRef Key, Block Contents) {
835     attributeImpl(Key, [&] { array(Contents); });
836   }
837   /// Emit an attribute whose value is an object with attributes from the Block.
attributeObject(llvm::StringRef Key,Block Contents)838   void attributeObject(llvm::StringRef Key, Block Contents) {
839     attributeImpl(Key, [&] { object(Contents); });
840   }
841 
842   // Low-level begin/end functions to output arrays, objects, and attributes.
843   // Must be correctly paired. Allowed contexts are as above.
844 
845   void arrayBegin();
846   void arrayEnd();
847   void objectBegin();
848   void objectEnd();
849   void attributeBegin(llvm::StringRef Key);
850   void attributeEnd();
851 
852  private:
attributeImpl(llvm::StringRef Key,Block Contents)853   void attributeImpl(llvm::StringRef Key, Block Contents) {
854     attributeBegin(Key);
855     Contents();
856     attributeEnd();
857   }
858 
859   void valueBegin();
860   void newline();
861 
862   enum Context {
863     Singleton, // Top level, or object attribute.
864     Array,
865     Object,
866   };
867   struct State {
868     Context Ctx = Singleton;
869     bool HasValue = false;
870   };
871   llvm::SmallVector<State, 16> Stack; // Never empty.
872   llvm::raw_ostream &OS;
873   unsigned IndentSize;
874   unsigned Indent = 0;
875 };
876 
877 /// Serializes this Value to JSON, writing it to the provided stream.
878 /// The formatting is compact (no extra whitespace) and deterministic.
879 /// For pretty-printing, use the formatv() format_provider below.
880 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Value &V) {
881   OStream(OS).value(V);
882   return OS;
883 }
884 } // namespace json
885 
886 /// Allow printing json::Value with formatv().
887 /// The default style is basic/compact formatting, like operator<<.
888 /// A format string like formatv("{0:2}", Value) pretty-prints with indent 2.
889 template <> struct format_provider<llvm::json::Value> {
890   static void format(const llvm::json::Value &, raw_ostream &, StringRef);
891 };
892 } // namespace llvm
893 
894 #endif
895