1*0b57cec5SDimitry Andric //=== JSON.cpp - JSON value, parsing and serialization - C++ -----------*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===---------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "llvm/Support/JSON.h" 10*0b57cec5SDimitry Andric #include "llvm/Support/ConvertUTF.h" 11*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 12*0b57cec5SDimitry Andric #include <cctype> 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric namespace llvm { 15*0b57cec5SDimitry Andric namespace json { 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric Value &Object::operator[](const ObjectKey &K) { 18*0b57cec5SDimitry Andric return try_emplace(K, nullptr).first->getSecond(); 19*0b57cec5SDimitry Andric } 20*0b57cec5SDimitry Andric Value &Object::operator[](ObjectKey &&K) { 21*0b57cec5SDimitry Andric return try_emplace(std::move(K), nullptr).first->getSecond(); 22*0b57cec5SDimitry Andric } 23*0b57cec5SDimitry Andric Value *Object::get(StringRef K) { 24*0b57cec5SDimitry Andric auto I = find(K); 25*0b57cec5SDimitry Andric if (I == end()) 26*0b57cec5SDimitry Andric return nullptr; 27*0b57cec5SDimitry Andric return &I->second; 28*0b57cec5SDimitry Andric } 29*0b57cec5SDimitry Andric const Value *Object::get(StringRef K) const { 30*0b57cec5SDimitry Andric auto I = find(K); 31*0b57cec5SDimitry Andric if (I == end()) 32*0b57cec5SDimitry Andric return nullptr; 33*0b57cec5SDimitry Andric return &I->second; 34*0b57cec5SDimitry Andric } 35*0b57cec5SDimitry Andric llvm::Optional<std::nullptr_t> Object::getNull(StringRef K) const { 36*0b57cec5SDimitry Andric if (auto *V = get(K)) 37*0b57cec5SDimitry Andric return V->getAsNull(); 38*0b57cec5SDimitry Andric return llvm::None; 39*0b57cec5SDimitry Andric } 40*0b57cec5SDimitry Andric llvm::Optional<bool> Object::getBoolean(StringRef K) const { 41*0b57cec5SDimitry Andric if (auto *V = get(K)) 42*0b57cec5SDimitry Andric return V->getAsBoolean(); 43*0b57cec5SDimitry Andric return llvm::None; 44*0b57cec5SDimitry Andric } 45*0b57cec5SDimitry Andric llvm::Optional<double> Object::getNumber(StringRef K) const { 46*0b57cec5SDimitry Andric if (auto *V = get(K)) 47*0b57cec5SDimitry Andric return V->getAsNumber(); 48*0b57cec5SDimitry Andric return llvm::None; 49*0b57cec5SDimitry Andric } 50*0b57cec5SDimitry Andric llvm::Optional<int64_t> Object::getInteger(StringRef K) const { 51*0b57cec5SDimitry Andric if (auto *V = get(K)) 52*0b57cec5SDimitry Andric return V->getAsInteger(); 53*0b57cec5SDimitry Andric return llvm::None; 54*0b57cec5SDimitry Andric } 55*0b57cec5SDimitry Andric llvm::Optional<llvm::StringRef> Object::getString(StringRef K) const { 56*0b57cec5SDimitry Andric if (auto *V = get(K)) 57*0b57cec5SDimitry Andric return V->getAsString(); 58*0b57cec5SDimitry Andric return llvm::None; 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric const json::Object *Object::getObject(StringRef K) const { 61*0b57cec5SDimitry Andric if (auto *V = get(K)) 62*0b57cec5SDimitry Andric return V->getAsObject(); 63*0b57cec5SDimitry Andric return nullptr; 64*0b57cec5SDimitry Andric } 65*0b57cec5SDimitry Andric json::Object *Object::getObject(StringRef K) { 66*0b57cec5SDimitry Andric if (auto *V = get(K)) 67*0b57cec5SDimitry Andric return V->getAsObject(); 68*0b57cec5SDimitry Andric return nullptr; 69*0b57cec5SDimitry Andric } 70*0b57cec5SDimitry Andric const json::Array *Object::getArray(StringRef K) const { 71*0b57cec5SDimitry Andric if (auto *V = get(K)) 72*0b57cec5SDimitry Andric return V->getAsArray(); 73*0b57cec5SDimitry Andric return nullptr; 74*0b57cec5SDimitry Andric } 75*0b57cec5SDimitry Andric json::Array *Object::getArray(StringRef K) { 76*0b57cec5SDimitry Andric if (auto *V = get(K)) 77*0b57cec5SDimitry Andric return V->getAsArray(); 78*0b57cec5SDimitry Andric return nullptr; 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric bool operator==(const Object &LHS, const Object &RHS) { 81*0b57cec5SDimitry Andric if (LHS.size() != RHS.size()) 82*0b57cec5SDimitry Andric return false; 83*0b57cec5SDimitry Andric for (const auto &L : LHS) { 84*0b57cec5SDimitry Andric auto R = RHS.find(L.first); 85*0b57cec5SDimitry Andric if (R == RHS.end() || L.second != R->second) 86*0b57cec5SDimitry Andric return false; 87*0b57cec5SDimitry Andric } 88*0b57cec5SDimitry Andric return true; 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric Array::Array(std::initializer_list<Value> Elements) { 92*0b57cec5SDimitry Andric V.reserve(Elements.size()); 93*0b57cec5SDimitry Andric for (const Value &V : Elements) { 94*0b57cec5SDimitry Andric emplace_back(nullptr); 95*0b57cec5SDimitry Andric back().moveFrom(std::move(V)); 96*0b57cec5SDimitry Andric } 97*0b57cec5SDimitry Andric } 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric Value::Value(std::initializer_list<Value> Elements) 100*0b57cec5SDimitry Andric : Value(json::Array(Elements)) {} 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric void Value::copyFrom(const Value &M) { 103*0b57cec5SDimitry Andric Type = M.Type; 104*0b57cec5SDimitry Andric switch (Type) { 105*0b57cec5SDimitry Andric case T_Null: 106*0b57cec5SDimitry Andric case T_Boolean: 107*0b57cec5SDimitry Andric case T_Double: 108*0b57cec5SDimitry Andric case T_Integer: 109*0b57cec5SDimitry Andric memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer)); 110*0b57cec5SDimitry Andric break; 111*0b57cec5SDimitry Andric case T_StringRef: 112*0b57cec5SDimitry Andric create<StringRef>(M.as<StringRef>()); 113*0b57cec5SDimitry Andric break; 114*0b57cec5SDimitry Andric case T_String: 115*0b57cec5SDimitry Andric create<std::string>(M.as<std::string>()); 116*0b57cec5SDimitry Andric break; 117*0b57cec5SDimitry Andric case T_Object: 118*0b57cec5SDimitry Andric create<json::Object>(M.as<json::Object>()); 119*0b57cec5SDimitry Andric break; 120*0b57cec5SDimitry Andric case T_Array: 121*0b57cec5SDimitry Andric create<json::Array>(M.as<json::Array>()); 122*0b57cec5SDimitry Andric break; 123*0b57cec5SDimitry Andric } 124*0b57cec5SDimitry Andric } 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric void Value::moveFrom(const Value &&M) { 127*0b57cec5SDimitry Andric Type = M.Type; 128*0b57cec5SDimitry Andric switch (Type) { 129*0b57cec5SDimitry Andric case T_Null: 130*0b57cec5SDimitry Andric case T_Boolean: 131*0b57cec5SDimitry Andric case T_Double: 132*0b57cec5SDimitry Andric case T_Integer: 133*0b57cec5SDimitry Andric memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer)); 134*0b57cec5SDimitry Andric break; 135*0b57cec5SDimitry Andric case T_StringRef: 136*0b57cec5SDimitry Andric create<StringRef>(M.as<StringRef>()); 137*0b57cec5SDimitry Andric break; 138*0b57cec5SDimitry Andric case T_String: 139*0b57cec5SDimitry Andric create<std::string>(std::move(M.as<std::string>())); 140*0b57cec5SDimitry Andric M.Type = T_Null; 141*0b57cec5SDimitry Andric break; 142*0b57cec5SDimitry Andric case T_Object: 143*0b57cec5SDimitry Andric create<json::Object>(std::move(M.as<json::Object>())); 144*0b57cec5SDimitry Andric M.Type = T_Null; 145*0b57cec5SDimitry Andric break; 146*0b57cec5SDimitry Andric case T_Array: 147*0b57cec5SDimitry Andric create<json::Array>(std::move(M.as<json::Array>())); 148*0b57cec5SDimitry Andric M.Type = T_Null; 149*0b57cec5SDimitry Andric break; 150*0b57cec5SDimitry Andric } 151*0b57cec5SDimitry Andric } 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric void Value::destroy() { 154*0b57cec5SDimitry Andric switch (Type) { 155*0b57cec5SDimitry Andric case T_Null: 156*0b57cec5SDimitry Andric case T_Boolean: 157*0b57cec5SDimitry Andric case T_Double: 158*0b57cec5SDimitry Andric case T_Integer: 159*0b57cec5SDimitry Andric break; 160*0b57cec5SDimitry Andric case T_StringRef: 161*0b57cec5SDimitry Andric as<StringRef>().~StringRef(); 162*0b57cec5SDimitry Andric break; 163*0b57cec5SDimitry Andric case T_String: 164*0b57cec5SDimitry Andric as<std::string>().~basic_string(); 165*0b57cec5SDimitry Andric break; 166*0b57cec5SDimitry Andric case T_Object: 167*0b57cec5SDimitry Andric as<json::Object>().~Object(); 168*0b57cec5SDimitry Andric break; 169*0b57cec5SDimitry Andric case T_Array: 170*0b57cec5SDimitry Andric as<json::Array>().~Array(); 171*0b57cec5SDimitry Andric break; 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric bool operator==(const Value &L, const Value &R) { 176*0b57cec5SDimitry Andric if (L.kind() != R.kind()) 177*0b57cec5SDimitry Andric return false; 178*0b57cec5SDimitry Andric switch (L.kind()) { 179*0b57cec5SDimitry Andric case Value::Null: 180*0b57cec5SDimitry Andric return *L.getAsNull() == *R.getAsNull(); 181*0b57cec5SDimitry Andric case Value::Boolean: 182*0b57cec5SDimitry Andric return *L.getAsBoolean() == *R.getAsBoolean(); 183*0b57cec5SDimitry Andric case Value::Number: 184*0b57cec5SDimitry Andric // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 185*0b57cec5SDimitry Andric // The same integer must convert to the same double, per the standard. 186*0b57cec5SDimitry Andric // However we see 64-vs-80-bit precision comparisons with gcc-7 -O3 -m32. 187*0b57cec5SDimitry Andric // So we avoid floating point promotion for exact comparisons. 188*0b57cec5SDimitry Andric if (L.Type == Value::T_Integer || R.Type == Value::T_Integer) 189*0b57cec5SDimitry Andric return L.getAsInteger() == R.getAsInteger(); 190*0b57cec5SDimitry Andric return *L.getAsNumber() == *R.getAsNumber(); 191*0b57cec5SDimitry Andric case Value::String: 192*0b57cec5SDimitry Andric return *L.getAsString() == *R.getAsString(); 193*0b57cec5SDimitry Andric case Value::Array: 194*0b57cec5SDimitry Andric return *L.getAsArray() == *R.getAsArray(); 195*0b57cec5SDimitry Andric case Value::Object: 196*0b57cec5SDimitry Andric return *L.getAsObject() == *R.getAsObject(); 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric llvm_unreachable("Unknown value kind"); 199*0b57cec5SDimitry Andric } 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric namespace { 202*0b57cec5SDimitry Andric // Simple recursive-descent JSON parser. 203*0b57cec5SDimitry Andric class Parser { 204*0b57cec5SDimitry Andric public: 205*0b57cec5SDimitry Andric Parser(StringRef JSON) 206*0b57cec5SDimitry Andric : Start(JSON.begin()), P(JSON.begin()), End(JSON.end()) {} 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric bool checkUTF8() { 209*0b57cec5SDimitry Andric size_t ErrOffset; 210*0b57cec5SDimitry Andric if (isUTF8(StringRef(Start, End - Start), &ErrOffset)) 211*0b57cec5SDimitry Andric return true; 212*0b57cec5SDimitry Andric P = Start + ErrOffset; // For line/column calculation. 213*0b57cec5SDimitry Andric return parseError("Invalid UTF-8 sequence"); 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric bool parseValue(Value &Out); 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric bool assertEnd() { 219*0b57cec5SDimitry Andric eatWhitespace(); 220*0b57cec5SDimitry Andric if (P == End) 221*0b57cec5SDimitry Andric return true; 222*0b57cec5SDimitry Andric return parseError("Text after end of document"); 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric Error takeError() { 226*0b57cec5SDimitry Andric assert(Err); 227*0b57cec5SDimitry Andric return std::move(*Err); 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric private: 231*0b57cec5SDimitry Andric void eatWhitespace() { 232*0b57cec5SDimitry Andric while (P != End && (*P == ' ' || *P == '\r' || *P == '\n' || *P == '\t')) 233*0b57cec5SDimitry Andric ++P; 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric // On invalid syntax, parseX() functions return false and set Err. 237*0b57cec5SDimitry Andric bool parseNumber(char First, Value &Out); 238*0b57cec5SDimitry Andric bool parseString(std::string &Out); 239*0b57cec5SDimitry Andric bool parseUnicode(std::string &Out); 240*0b57cec5SDimitry Andric bool parseError(const char *Msg); // always returns false 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric char next() { return P == End ? 0 : *P++; } 243*0b57cec5SDimitry Andric char peek() { return P == End ? 0 : *P; } 244*0b57cec5SDimitry Andric static bool isNumber(char C) { 245*0b57cec5SDimitry Andric return C == '0' || C == '1' || C == '2' || C == '3' || C == '4' || 246*0b57cec5SDimitry Andric C == '5' || C == '6' || C == '7' || C == '8' || C == '9' || 247*0b57cec5SDimitry Andric C == 'e' || C == 'E' || C == '+' || C == '-' || C == '.'; 248*0b57cec5SDimitry Andric } 249*0b57cec5SDimitry Andric 250*0b57cec5SDimitry Andric Optional<Error> Err; 251*0b57cec5SDimitry Andric const char *Start, *P, *End; 252*0b57cec5SDimitry Andric }; 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric bool Parser::parseValue(Value &Out) { 255*0b57cec5SDimitry Andric eatWhitespace(); 256*0b57cec5SDimitry Andric if (P == End) 257*0b57cec5SDimitry Andric return parseError("Unexpected EOF"); 258*0b57cec5SDimitry Andric switch (char C = next()) { 259*0b57cec5SDimitry Andric // Bare null/true/false are easy - first char identifies them. 260*0b57cec5SDimitry Andric case 'n': 261*0b57cec5SDimitry Andric Out = nullptr; 262*0b57cec5SDimitry Andric return (next() == 'u' && next() == 'l' && next() == 'l') || 263*0b57cec5SDimitry Andric parseError("Invalid JSON value (null?)"); 264*0b57cec5SDimitry Andric case 't': 265*0b57cec5SDimitry Andric Out = true; 266*0b57cec5SDimitry Andric return (next() == 'r' && next() == 'u' && next() == 'e') || 267*0b57cec5SDimitry Andric parseError("Invalid JSON value (true?)"); 268*0b57cec5SDimitry Andric case 'f': 269*0b57cec5SDimitry Andric Out = false; 270*0b57cec5SDimitry Andric return (next() == 'a' && next() == 'l' && next() == 's' && next() == 'e') || 271*0b57cec5SDimitry Andric parseError("Invalid JSON value (false?)"); 272*0b57cec5SDimitry Andric case '"': { 273*0b57cec5SDimitry Andric std::string S; 274*0b57cec5SDimitry Andric if (parseString(S)) { 275*0b57cec5SDimitry Andric Out = std::move(S); 276*0b57cec5SDimitry Andric return true; 277*0b57cec5SDimitry Andric } 278*0b57cec5SDimitry Andric return false; 279*0b57cec5SDimitry Andric } 280*0b57cec5SDimitry Andric case '[': { 281*0b57cec5SDimitry Andric Out = Array{}; 282*0b57cec5SDimitry Andric Array &A = *Out.getAsArray(); 283*0b57cec5SDimitry Andric eatWhitespace(); 284*0b57cec5SDimitry Andric if (peek() == ']') { 285*0b57cec5SDimitry Andric ++P; 286*0b57cec5SDimitry Andric return true; 287*0b57cec5SDimitry Andric } 288*0b57cec5SDimitry Andric for (;;) { 289*0b57cec5SDimitry Andric A.emplace_back(nullptr); 290*0b57cec5SDimitry Andric if (!parseValue(A.back())) 291*0b57cec5SDimitry Andric return false; 292*0b57cec5SDimitry Andric eatWhitespace(); 293*0b57cec5SDimitry Andric switch (next()) { 294*0b57cec5SDimitry Andric case ',': 295*0b57cec5SDimitry Andric eatWhitespace(); 296*0b57cec5SDimitry Andric continue; 297*0b57cec5SDimitry Andric case ']': 298*0b57cec5SDimitry Andric return true; 299*0b57cec5SDimitry Andric default: 300*0b57cec5SDimitry Andric return parseError("Expected , or ] after array element"); 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric } 303*0b57cec5SDimitry Andric } 304*0b57cec5SDimitry Andric case '{': { 305*0b57cec5SDimitry Andric Out = Object{}; 306*0b57cec5SDimitry Andric Object &O = *Out.getAsObject(); 307*0b57cec5SDimitry Andric eatWhitespace(); 308*0b57cec5SDimitry Andric if (peek() == '}') { 309*0b57cec5SDimitry Andric ++P; 310*0b57cec5SDimitry Andric return true; 311*0b57cec5SDimitry Andric } 312*0b57cec5SDimitry Andric for (;;) { 313*0b57cec5SDimitry Andric if (next() != '"') 314*0b57cec5SDimitry Andric return parseError("Expected object key"); 315*0b57cec5SDimitry Andric std::string K; 316*0b57cec5SDimitry Andric if (!parseString(K)) 317*0b57cec5SDimitry Andric return false; 318*0b57cec5SDimitry Andric eatWhitespace(); 319*0b57cec5SDimitry Andric if (next() != ':') 320*0b57cec5SDimitry Andric return parseError("Expected : after object key"); 321*0b57cec5SDimitry Andric eatWhitespace(); 322*0b57cec5SDimitry Andric if (!parseValue(O[std::move(K)])) 323*0b57cec5SDimitry Andric return false; 324*0b57cec5SDimitry Andric eatWhitespace(); 325*0b57cec5SDimitry Andric switch (next()) { 326*0b57cec5SDimitry Andric case ',': 327*0b57cec5SDimitry Andric eatWhitespace(); 328*0b57cec5SDimitry Andric continue; 329*0b57cec5SDimitry Andric case '}': 330*0b57cec5SDimitry Andric return true; 331*0b57cec5SDimitry Andric default: 332*0b57cec5SDimitry Andric return parseError("Expected , or } after object property"); 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric } 335*0b57cec5SDimitry Andric } 336*0b57cec5SDimitry Andric default: 337*0b57cec5SDimitry Andric if (isNumber(C)) 338*0b57cec5SDimitry Andric return parseNumber(C, Out); 339*0b57cec5SDimitry Andric return parseError("Invalid JSON value"); 340*0b57cec5SDimitry Andric } 341*0b57cec5SDimitry Andric } 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric bool Parser::parseNumber(char First, Value &Out) { 344*0b57cec5SDimitry Andric // Read the number into a string. (Must be null-terminated for strto*). 345*0b57cec5SDimitry Andric SmallString<24> S; 346*0b57cec5SDimitry Andric S.push_back(First); 347*0b57cec5SDimitry Andric while (isNumber(peek())) 348*0b57cec5SDimitry Andric S.push_back(next()); 349*0b57cec5SDimitry Andric char *End; 350*0b57cec5SDimitry Andric // Try first to parse as integer, and if so preserve full 64 bits. 351*0b57cec5SDimitry Andric // strtoll returns long long >= 64 bits, so check it's in range too. 352*0b57cec5SDimitry Andric auto I = std::strtoll(S.c_str(), &End, 10); 353*0b57cec5SDimitry Andric if (End == S.end() && I >= std::numeric_limits<int64_t>::min() && 354*0b57cec5SDimitry Andric I <= std::numeric_limits<int64_t>::max()) { 355*0b57cec5SDimitry Andric Out = int64_t(I); 356*0b57cec5SDimitry Andric return true; 357*0b57cec5SDimitry Andric } 358*0b57cec5SDimitry Andric // If it's not an integer 359*0b57cec5SDimitry Andric Out = std::strtod(S.c_str(), &End); 360*0b57cec5SDimitry Andric return End == S.end() || parseError("Invalid JSON value (number?)"); 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric bool Parser::parseString(std::string &Out) { 364*0b57cec5SDimitry Andric // leading quote was already consumed. 365*0b57cec5SDimitry Andric for (char C = next(); C != '"'; C = next()) { 366*0b57cec5SDimitry Andric if (LLVM_UNLIKELY(P == End)) 367*0b57cec5SDimitry Andric return parseError("Unterminated string"); 368*0b57cec5SDimitry Andric if (LLVM_UNLIKELY((C & 0x1f) == C)) 369*0b57cec5SDimitry Andric return parseError("Control character in string"); 370*0b57cec5SDimitry Andric if (LLVM_LIKELY(C != '\\')) { 371*0b57cec5SDimitry Andric Out.push_back(C); 372*0b57cec5SDimitry Andric continue; 373*0b57cec5SDimitry Andric } 374*0b57cec5SDimitry Andric // Handle escape sequence. 375*0b57cec5SDimitry Andric switch (C = next()) { 376*0b57cec5SDimitry Andric case '"': 377*0b57cec5SDimitry Andric case '\\': 378*0b57cec5SDimitry Andric case '/': 379*0b57cec5SDimitry Andric Out.push_back(C); 380*0b57cec5SDimitry Andric break; 381*0b57cec5SDimitry Andric case 'b': 382*0b57cec5SDimitry Andric Out.push_back('\b'); 383*0b57cec5SDimitry Andric break; 384*0b57cec5SDimitry Andric case 'f': 385*0b57cec5SDimitry Andric Out.push_back('\f'); 386*0b57cec5SDimitry Andric break; 387*0b57cec5SDimitry Andric case 'n': 388*0b57cec5SDimitry Andric Out.push_back('\n'); 389*0b57cec5SDimitry Andric break; 390*0b57cec5SDimitry Andric case 'r': 391*0b57cec5SDimitry Andric Out.push_back('\r'); 392*0b57cec5SDimitry Andric break; 393*0b57cec5SDimitry Andric case 't': 394*0b57cec5SDimitry Andric Out.push_back('\t'); 395*0b57cec5SDimitry Andric break; 396*0b57cec5SDimitry Andric case 'u': 397*0b57cec5SDimitry Andric if (!parseUnicode(Out)) 398*0b57cec5SDimitry Andric return false; 399*0b57cec5SDimitry Andric break; 400*0b57cec5SDimitry Andric default: 401*0b57cec5SDimitry Andric return parseError("Invalid escape sequence"); 402*0b57cec5SDimitry Andric } 403*0b57cec5SDimitry Andric } 404*0b57cec5SDimitry Andric return true; 405*0b57cec5SDimitry Andric } 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andric static void encodeUtf8(uint32_t Rune, std::string &Out) { 408*0b57cec5SDimitry Andric if (Rune < 0x80) { 409*0b57cec5SDimitry Andric Out.push_back(Rune & 0x7F); 410*0b57cec5SDimitry Andric } else if (Rune < 0x800) { 411*0b57cec5SDimitry Andric uint8_t FirstByte = 0xC0 | ((Rune & 0x7C0) >> 6); 412*0b57cec5SDimitry Andric uint8_t SecondByte = 0x80 | (Rune & 0x3F); 413*0b57cec5SDimitry Andric Out.push_back(FirstByte); 414*0b57cec5SDimitry Andric Out.push_back(SecondByte); 415*0b57cec5SDimitry Andric } else if (Rune < 0x10000) { 416*0b57cec5SDimitry Andric uint8_t FirstByte = 0xE0 | ((Rune & 0xF000) >> 12); 417*0b57cec5SDimitry Andric uint8_t SecondByte = 0x80 | ((Rune & 0xFC0) >> 6); 418*0b57cec5SDimitry Andric uint8_t ThirdByte = 0x80 | (Rune & 0x3F); 419*0b57cec5SDimitry Andric Out.push_back(FirstByte); 420*0b57cec5SDimitry Andric Out.push_back(SecondByte); 421*0b57cec5SDimitry Andric Out.push_back(ThirdByte); 422*0b57cec5SDimitry Andric } else if (Rune < 0x110000) { 423*0b57cec5SDimitry Andric uint8_t FirstByte = 0xF0 | ((Rune & 0x1F0000) >> 18); 424*0b57cec5SDimitry Andric uint8_t SecondByte = 0x80 | ((Rune & 0x3F000) >> 12); 425*0b57cec5SDimitry Andric uint8_t ThirdByte = 0x80 | ((Rune & 0xFC0) >> 6); 426*0b57cec5SDimitry Andric uint8_t FourthByte = 0x80 | (Rune & 0x3F); 427*0b57cec5SDimitry Andric Out.push_back(FirstByte); 428*0b57cec5SDimitry Andric Out.push_back(SecondByte); 429*0b57cec5SDimitry Andric Out.push_back(ThirdByte); 430*0b57cec5SDimitry Andric Out.push_back(FourthByte); 431*0b57cec5SDimitry Andric } else { 432*0b57cec5SDimitry Andric llvm_unreachable("Invalid codepoint"); 433*0b57cec5SDimitry Andric } 434*0b57cec5SDimitry Andric } 435*0b57cec5SDimitry Andric 436*0b57cec5SDimitry Andric // Parse a UTF-16 \uNNNN escape sequence. "\u" has already been consumed. 437*0b57cec5SDimitry Andric // May parse several sequential escapes to ensure proper surrogate handling. 438*0b57cec5SDimitry Andric // We do not use ConvertUTF.h, it can't accept and replace unpaired surrogates. 439*0b57cec5SDimitry Andric // These are invalid Unicode but valid JSON (RFC 8259, section 8.2). 440*0b57cec5SDimitry Andric bool Parser::parseUnicode(std::string &Out) { 441*0b57cec5SDimitry Andric // Invalid UTF is not a JSON error (RFC 8529§8.2). It gets replaced by U+FFFD. 442*0b57cec5SDimitry Andric auto Invalid = [&] { Out.append(/* UTF-8 */ {'\xef', '\xbf', '\xbd'}); }; 443*0b57cec5SDimitry Andric // Decodes 4 hex digits from the stream into Out, returns false on error. 444*0b57cec5SDimitry Andric auto Parse4Hex = [this](uint16_t &Out) -> bool { 445*0b57cec5SDimitry Andric Out = 0; 446*0b57cec5SDimitry Andric char Bytes[] = {next(), next(), next(), next()}; 447*0b57cec5SDimitry Andric for (unsigned char C : Bytes) { 448*0b57cec5SDimitry Andric if (!std::isxdigit(C)) 449*0b57cec5SDimitry Andric return parseError("Invalid \\u escape sequence"); 450*0b57cec5SDimitry Andric Out <<= 4; 451*0b57cec5SDimitry Andric Out |= (C > '9') ? (C & ~0x20) - 'A' + 10 : (C - '0'); 452*0b57cec5SDimitry Andric } 453*0b57cec5SDimitry Andric return true; 454*0b57cec5SDimitry Andric }; 455*0b57cec5SDimitry Andric uint16_t First; // UTF-16 code unit from the first \u escape. 456*0b57cec5SDimitry Andric if (!Parse4Hex(First)) 457*0b57cec5SDimitry Andric return false; 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric // We loop to allow proper surrogate-pair error handling. 460*0b57cec5SDimitry Andric while (true) { 461*0b57cec5SDimitry Andric // Case 1: the UTF-16 code unit is already a codepoint in the BMP. 462*0b57cec5SDimitry Andric if (LLVM_LIKELY(First < 0xD800 || First >= 0xE000)) { 463*0b57cec5SDimitry Andric encodeUtf8(First, Out); 464*0b57cec5SDimitry Andric return true; 465*0b57cec5SDimitry Andric } 466*0b57cec5SDimitry Andric 467*0b57cec5SDimitry Andric // Case 2: it's an (unpaired) trailing surrogate. 468*0b57cec5SDimitry Andric if (LLVM_UNLIKELY(First >= 0xDC00)) { 469*0b57cec5SDimitry Andric Invalid(); 470*0b57cec5SDimitry Andric return true; 471*0b57cec5SDimitry Andric } 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric // Case 3: it's a leading surrogate. We expect a trailing one next. 474*0b57cec5SDimitry Andric // Case 3a: there's no trailing \u escape. Don't advance in the stream. 475*0b57cec5SDimitry Andric if (LLVM_UNLIKELY(P + 2 > End || *P != '\\' || *(P + 1) != 'u')) { 476*0b57cec5SDimitry Andric Invalid(); // Leading surrogate was unpaired. 477*0b57cec5SDimitry Andric return true; 478*0b57cec5SDimitry Andric } 479*0b57cec5SDimitry Andric P += 2; 480*0b57cec5SDimitry Andric uint16_t Second; 481*0b57cec5SDimitry Andric if (!Parse4Hex(Second)) 482*0b57cec5SDimitry Andric return false; 483*0b57cec5SDimitry Andric // Case 3b: there was another \u escape, but it wasn't a trailing surrogate. 484*0b57cec5SDimitry Andric if (LLVM_UNLIKELY(Second < 0xDC00 || Second >= 0xE000)) { 485*0b57cec5SDimitry Andric Invalid(); // Leading surrogate was unpaired. 486*0b57cec5SDimitry Andric First = Second; // Second escape still needs to be processed. 487*0b57cec5SDimitry Andric continue; 488*0b57cec5SDimitry Andric } 489*0b57cec5SDimitry Andric // Case 3c: a valid surrogate pair encoding an astral codepoint. 490*0b57cec5SDimitry Andric encodeUtf8(0x10000 | ((First - 0xD800) << 10) | (Second - 0xDC00), Out); 491*0b57cec5SDimitry Andric return true; 492*0b57cec5SDimitry Andric } 493*0b57cec5SDimitry Andric } 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric bool Parser::parseError(const char *Msg) { 496*0b57cec5SDimitry Andric int Line = 1; 497*0b57cec5SDimitry Andric const char *StartOfLine = Start; 498*0b57cec5SDimitry Andric for (const char *X = Start; X < P; ++X) { 499*0b57cec5SDimitry Andric if (*X == 0x0A) { 500*0b57cec5SDimitry Andric ++Line; 501*0b57cec5SDimitry Andric StartOfLine = X + 1; 502*0b57cec5SDimitry Andric } 503*0b57cec5SDimitry Andric } 504*0b57cec5SDimitry Andric Err.emplace( 5058bcb0991SDimitry Andric std::make_unique<ParseError>(Msg, Line, P - StartOfLine, P - Start)); 506*0b57cec5SDimitry Andric return false; 507*0b57cec5SDimitry Andric } 508*0b57cec5SDimitry Andric } // namespace 509*0b57cec5SDimitry Andric 510*0b57cec5SDimitry Andric Expected<Value> parse(StringRef JSON) { 511*0b57cec5SDimitry Andric Parser P(JSON); 512*0b57cec5SDimitry Andric Value E = nullptr; 513*0b57cec5SDimitry Andric if (P.checkUTF8()) 514*0b57cec5SDimitry Andric if (P.parseValue(E)) 515*0b57cec5SDimitry Andric if (P.assertEnd()) 516*0b57cec5SDimitry Andric return std::move(E); 517*0b57cec5SDimitry Andric return P.takeError(); 518*0b57cec5SDimitry Andric } 519*0b57cec5SDimitry Andric char ParseError::ID = 0; 520*0b57cec5SDimitry Andric 521*0b57cec5SDimitry Andric static std::vector<const Object::value_type *> sortedElements(const Object &O) { 522*0b57cec5SDimitry Andric std::vector<const Object::value_type *> Elements; 523*0b57cec5SDimitry Andric for (const auto &E : O) 524*0b57cec5SDimitry Andric Elements.push_back(&E); 525*0b57cec5SDimitry Andric llvm::sort(Elements, 526*0b57cec5SDimitry Andric [](const Object::value_type *L, const Object::value_type *R) { 527*0b57cec5SDimitry Andric return L->first < R->first; 528*0b57cec5SDimitry Andric }); 529*0b57cec5SDimitry Andric return Elements; 530*0b57cec5SDimitry Andric } 531*0b57cec5SDimitry Andric 532*0b57cec5SDimitry Andric bool isUTF8(llvm::StringRef S, size_t *ErrOffset) { 533*0b57cec5SDimitry Andric // Fast-path for ASCII, which is valid UTF-8. 534*0b57cec5SDimitry Andric if (LLVM_LIKELY(isASCII(S))) 535*0b57cec5SDimitry Andric return true; 536*0b57cec5SDimitry Andric 537*0b57cec5SDimitry Andric const UTF8 *Data = reinterpret_cast<const UTF8 *>(S.data()), *Rest = Data; 538*0b57cec5SDimitry Andric if (LLVM_LIKELY(isLegalUTF8String(&Rest, Data + S.size()))) 539*0b57cec5SDimitry Andric return true; 540*0b57cec5SDimitry Andric 541*0b57cec5SDimitry Andric if (ErrOffset) 542*0b57cec5SDimitry Andric *ErrOffset = Rest - Data; 543*0b57cec5SDimitry Andric return false; 544*0b57cec5SDimitry Andric } 545*0b57cec5SDimitry Andric 546*0b57cec5SDimitry Andric std::string fixUTF8(llvm::StringRef S) { 547*0b57cec5SDimitry Andric // This isn't particularly efficient, but is only for error-recovery. 548*0b57cec5SDimitry Andric std::vector<UTF32> Codepoints(S.size()); // 1 codepoint per byte suffices. 549*0b57cec5SDimitry Andric const UTF8 *In8 = reinterpret_cast<const UTF8 *>(S.data()); 550*0b57cec5SDimitry Andric UTF32 *Out32 = Codepoints.data(); 551*0b57cec5SDimitry Andric ConvertUTF8toUTF32(&In8, In8 + S.size(), &Out32, Out32 + Codepoints.size(), 552*0b57cec5SDimitry Andric lenientConversion); 553*0b57cec5SDimitry Andric Codepoints.resize(Out32 - Codepoints.data()); 554*0b57cec5SDimitry Andric std::string Res(4 * Codepoints.size(), 0); // 4 bytes per codepoint suffice 555*0b57cec5SDimitry Andric const UTF32 *In32 = Codepoints.data(); 556*0b57cec5SDimitry Andric UTF8 *Out8 = reinterpret_cast<UTF8 *>(&Res[0]); 557*0b57cec5SDimitry Andric ConvertUTF32toUTF8(&In32, In32 + Codepoints.size(), &Out8, Out8 + Res.size(), 558*0b57cec5SDimitry Andric strictConversion); 559*0b57cec5SDimitry Andric Res.resize(reinterpret_cast<char *>(Out8) - Res.data()); 560*0b57cec5SDimitry Andric return Res; 561*0b57cec5SDimitry Andric } 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric static void quote(llvm::raw_ostream &OS, llvm::StringRef S) { 564*0b57cec5SDimitry Andric OS << '\"'; 565*0b57cec5SDimitry Andric for (unsigned char C : S) { 566*0b57cec5SDimitry Andric if (C == 0x22 || C == 0x5C) 567*0b57cec5SDimitry Andric OS << '\\'; 568*0b57cec5SDimitry Andric if (C >= 0x20) { 569*0b57cec5SDimitry Andric OS << C; 570*0b57cec5SDimitry Andric continue; 571*0b57cec5SDimitry Andric } 572*0b57cec5SDimitry Andric OS << '\\'; 573*0b57cec5SDimitry Andric switch (C) { 574*0b57cec5SDimitry Andric // A few characters are common enough to make short escapes worthwhile. 575*0b57cec5SDimitry Andric case '\t': 576*0b57cec5SDimitry Andric OS << 't'; 577*0b57cec5SDimitry Andric break; 578*0b57cec5SDimitry Andric case '\n': 579*0b57cec5SDimitry Andric OS << 'n'; 580*0b57cec5SDimitry Andric break; 581*0b57cec5SDimitry Andric case '\r': 582*0b57cec5SDimitry Andric OS << 'r'; 583*0b57cec5SDimitry Andric break; 584*0b57cec5SDimitry Andric default: 585*0b57cec5SDimitry Andric OS << 'u'; 586*0b57cec5SDimitry Andric llvm::write_hex(OS, C, llvm::HexPrintStyle::Lower, 4); 587*0b57cec5SDimitry Andric break; 588*0b57cec5SDimitry Andric } 589*0b57cec5SDimitry Andric } 590*0b57cec5SDimitry Andric OS << '\"'; 591*0b57cec5SDimitry Andric } 592*0b57cec5SDimitry Andric 593*0b57cec5SDimitry Andric void llvm::json::OStream::value(const Value &V) { 594*0b57cec5SDimitry Andric switch (V.kind()) { 595*0b57cec5SDimitry Andric case Value::Null: 596*0b57cec5SDimitry Andric valueBegin(); 597*0b57cec5SDimitry Andric OS << "null"; 598*0b57cec5SDimitry Andric return; 599*0b57cec5SDimitry Andric case Value::Boolean: 600*0b57cec5SDimitry Andric valueBegin(); 601*0b57cec5SDimitry Andric OS << (*V.getAsBoolean() ? "true" : "false"); 602*0b57cec5SDimitry Andric return; 603*0b57cec5SDimitry Andric case Value::Number: 604*0b57cec5SDimitry Andric valueBegin(); 605*0b57cec5SDimitry Andric if (V.Type == Value::T_Integer) 606*0b57cec5SDimitry Andric OS << *V.getAsInteger(); 607*0b57cec5SDimitry Andric else 608*0b57cec5SDimitry Andric OS << format("%.*g", std::numeric_limits<double>::max_digits10, 609*0b57cec5SDimitry Andric *V.getAsNumber()); 610*0b57cec5SDimitry Andric return; 611*0b57cec5SDimitry Andric case Value::String: 612*0b57cec5SDimitry Andric valueBegin(); 613*0b57cec5SDimitry Andric quote(OS, *V.getAsString()); 614*0b57cec5SDimitry Andric return; 615*0b57cec5SDimitry Andric case Value::Array: 616*0b57cec5SDimitry Andric return array([&] { 617*0b57cec5SDimitry Andric for (const Value &E : *V.getAsArray()) 618*0b57cec5SDimitry Andric value(E); 619*0b57cec5SDimitry Andric }); 620*0b57cec5SDimitry Andric case Value::Object: 621*0b57cec5SDimitry Andric return object([&] { 622*0b57cec5SDimitry Andric for (const Object::value_type *E : sortedElements(*V.getAsObject())) 623*0b57cec5SDimitry Andric attribute(E->first, E->second); 624*0b57cec5SDimitry Andric }); 625*0b57cec5SDimitry Andric } 626*0b57cec5SDimitry Andric } 627*0b57cec5SDimitry Andric 628*0b57cec5SDimitry Andric void llvm::json::OStream::valueBegin() { 629*0b57cec5SDimitry Andric assert(Stack.back().Ctx != Object && "Only attributes allowed here"); 630*0b57cec5SDimitry Andric if (Stack.back().HasValue) { 631*0b57cec5SDimitry Andric assert(Stack.back().Ctx != Singleton && "Only one value allowed here"); 632*0b57cec5SDimitry Andric OS << ','; 633*0b57cec5SDimitry Andric } 634*0b57cec5SDimitry Andric if (Stack.back().Ctx == Array) 635*0b57cec5SDimitry Andric newline(); 636*0b57cec5SDimitry Andric Stack.back().HasValue = true; 637*0b57cec5SDimitry Andric } 638*0b57cec5SDimitry Andric 639*0b57cec5SDimitry Andric void llvm::json::OStream::newline() { 640*0b57cec5SDimitry Andric if (IndentSize) { 641*0b57cec5SDimitry Andric OS.write('\n'); 642*0b57cec5SDimitry Andric OS.indent(Indent); 643*0b57cec5SDimitry Andric } 644*0b57cec5SDimitry Andric } 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric void llvm::json::OStream::arrayBegin() { 647*0b57cec5SDimitry Andric valueBegin(); 648*0b57cec5SDimitry Andric Stack.emplace_back(); 649*0b57cec5SDimitry Andric Stack.back().Ctx = Array; 650*0b57cec5SDimitry Andric Indent += IndentSize; 651*0b57cec5SDimitry Andric OS << '['; 652*0b57cec5SDimitry Andric } 653*0b57cec5SDimitry Andric 654*0b57cec5SDimitry Andric void llvm::json::OStream::arrayEnd() { 655*0b57cec5SDimitry Andric assert(Stack.back().Ctx == Array); 656*0b57cec5SDimitry Andric Indent -= IndentSize; 657*0b57cec5SDimitry Andric if (Stack.back().HasValue) 658*0b57cec5SDimitry Andric newline(); 659*0b57cec5SDimitry Andric OS << ']'; 660*0b57cec5SDimitry Andric Stack.pop_back(); 661*0b57cec5SDimitry Andric assert(!Stack.empty()); 662*0b57cec5SDimitry Andric } 663*0b57cec5SDimitry Andric 664*0b57cec5SDimitry Andric void llvm::json::OStream::objectBegin() { 665*0b57cec5SDimitry Andric valueBegin(); 666*0b57cec5SDimitry Andric Stack.emplace_back(); 667*0b57cec5SDimitry Andric Stack.back().Ctx = Object; 668*0b57cec5SDimitry Andric Indent += IndentSize; 669*0b57cec5SDimitry Andric OS << '{'; 670*0b57cec5SDimitry Andric } 671*0b57cec5SDimitry Andric 672*0b57cec5SDimitry Andric void llvm::json::OStream::objectEnd() { 673*0b57cec5SDimitry Andric assert(Stack.back().Ctx == Object); 674*0b57cec5SDimitry Andric Indent -= IndentSize; 675*0b57cec5SDimitry Andric if (Stack.back().HasValue) 676*0b57cec5SDimitry Andric newline(); 677*0b57cec5SDimitry Andric OS << '}'; 678*0b57cec5SDimitry Andric Stack.pop_back(); 679*0b57cec5SDimitry Andric assert(!Stack.empty()); 680*0b57cec5SDimitry Andric } 681*0b57cec5SDimitry Andric 682*0b57cec5SDimitry Andric void llvm::json::OStream::attributeBegin(llvm::StringRef Key) { 683*0b57cec5SDimitry Andric assert(Stack.back().Ctx == Object); 684*0b57cec5SDimitry Andric if (Stack.back().HasValue) 685*0b57cec5SDimitry Andric OS << ','; 686*0b57cec5SDimitry Andric newline(); 687*0b57cec5SDimitry Andric Stack.back().HasValue = true; 688*0b57cec5SDimitry Andric Stack.emplace_back(); 689*0b57cec5SDimitry Andric Stack.back().Ctx = Singleton; 690*0b57cec5SDimitry Andric if (LLVM_LIKELY(isUTF8(Key))) { 691*0b57cec5SDimitry Andric quote(OS, Key); 692*0b57cec5SDimitry Andric } else { 693*0b57cec5SDimitry Andric assert(false && "Invalid UTF-8 in attribute key"); 694*0b57cec5SDimitry Andric quote(OS, fixUTF8(Key)); 695*0b57cec5SDimitry Andric } 696*0b57cec5SDimitry Andric OS.write(':'); 697*0b57cec5SDimitry Andric if (IndentSize) 698*0b57cec5SDimitry Andric OS.write(' '); 699*0b57cec5SDimitry Andric } 700*0b57cec5SDimitry Andric 701*0b57cec5SDimitry Andric void llvm::json::OStream::attributeEnd() { 702*0b57cec5SDimitry Andric assert(Stack.back().Ctx == Singleton); 703*0b57cec5SDimitry Andric assert(Stack.back().HasValue && "Attribute must have a value"); 704*0b57cec5SDimitry Andric Stack.pop_back(); 705*0b57cec5SDimitry Andric assert(Stack.back().Ctx == Object); 706*0b57cec5SDimitry Andric } 707*0b57cec5SDimitry Andric 708*0b57cec5SDimitry Andric } // namespace json 709*0b57cec5SDimitry Andric } // namespace llvm 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andric void llvm::format_provider<llvm::json::Value>::format( 712*0b57cec5SDimitry Andric const llvm::json::Value &E, raw_ostream &OS, StringRef Options) { 713*0b57cec5SDimitry Andric unsigned IndentAmount = 0; 714*0b57cec5SDimitry Andric if (!Options.empty() && Options.getAsInteger(/*Radix=*/10, IndentAmount)) 715*0b57cec5SDimitry Andric llvm_unreachable("json::Value format options should be an integer"); 716*0b57cec5SDimitry Andric json::OStream(OS, IndentAmount).value(E); 717*0b57cec5SDimitry Andric } 718*0b57cec5SDimitry Andric 719