175930019STodd Fiala //===---------------------JSON.h --------------------------------*- C++ -*-===// 275930019STodd Fiala // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 675930019STodd Fiala // 775930019STodd Fiala //===----------------------------------------------------------------------===// 875930019STodd Fiala 9cdc514e4SJonas Devlieghere #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H 10cdc514e4SJonas Devlieghere #define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H 1175930019STodd Fiala 1272090c21SPavel Labath #include "StdStringExtractor.h" 1375930019STodd Fiala 1475930019STodd Fiala // C includes 15*76e47d48SRaphael Isemann #include <cinttypes> 16*76e47d48SRaphael Isemann #include <cstdint> 1775930019STodd Fiala 1875930019STodd Fiala // C++ includes 1975930019STodd Fiala #include <map> 2075930019STodd Fiala #include <memory> 2175930019STodd Fiala #include <ostream> 2275930019STodd Fiala #include <string> 2375930019STodd Fiala #include <vector> 2475930019STodd Fiala 25b9c1b51eSKate Stone class JSONValue { 2675930019STodd Fiala public: 27b9c1b51eSKate Stone virtual void Write(std::ostream &s) = 0; 2875930019STodd Fiala 2975930019STodd Fiala typedef std::shared_ptr<JSONValue> SP; 3075930019STodd Fiala 31b9c1b51eSKate Stone enum class Kind { String, Number, True, False, Null, Object, Array }; 3275930019STodd Fiala JSONValue(Kind k)33b9c1b51eSKate Stone JSONValue(Kind k) : m_kind(k) {} 3475930019STodd Fiala GetKind()35b9c1b51eSKate Stone Kind GetKind() const { return m_kind; } 3675930019STodd Fiala 37b9c1b51eSKate Stone virtual ~JSONValue() = default; 3875930019STodd Fiala 3975930019STodd Fiala private: 4075930019STodd Fiala const Kind m_kind; 4175930019STodd Fiala }; 4275930019STodd Fiala 43b9c1b51eSKate Stone class JSONString : public JSONValue { 4475930019STodd Fiala public: 4575930019STodd Fiala JSONString(); 4675930019STodd Fiala JSONString(const char *s); 4775930019STodd Fiala JSONString(const std::string &s); 4875930019STodd Fiala 4975930019STodd Fiala JSONString(const JSONString &s) = delete; 50b9c1b51eSKate Stone JSONString &operator=(const JSONString &s) = delete; 5175930019STodd Fiala 52b9c1b51eSKate Stone void Write(std::ostream &s) override; 5375930019STodd Fiala 5475930019STodd Fiala typedef std::shared_ptr<JSONString> SP; 5575930019STodd Fiala GetData()56b9c1b51eSKate Stone std::string GetData() { return m_data; } 5775930019STodd Fiala classof(const JSONValue * V)58b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 5975930019STodd Fiala return V->GetKind() == JSONValue::Kind::String; 6075930019STodd Fiala } 6175930019STodd Fiala 6275930019STodd Fiala ~JSONString() override = default; 6375930019STodd Fiala 6475930019STodd Fiala private: 65b9c1b51eSKate Stone static std::string json_string_quote_metachars(const std::string &); 6675930019STodd Fiala 6775930019STodd Fiala std::string m_data; 6875930019STodd Fiala }; 6975930019STodd Fiala 70b9c1b51eSKate Stone class JSONNumber : public JSONValue { 7175930019STodd Fiala public: 7275930019STodd Fiala typedef std::shared_ptr<JSONNumber> SP; 7375930019STodd Fiala 74b9c1b51eSKate Stone // We cretae a constructor for all integer and floating point type with using 75b9c1b51eSKate Stone // templates and 76b9c1b51eSKate Stone // SFINAE to avoid having ambiguous overloads because of the implicit type 77b9c1b51eSKate Stone // promotion. If we 78b9c1b51eSKate Stone // would have constructors only with int64_t, uint64_t and double types then 79b9c1b51eSKate Stone // constructing a 80b9c1b51eSKate Stone // JSONNumber from an int32_t (or any other similar type) would fail to 81b9c1b51eSKate Stone // compile. 8275930019STodd Fiala 83b9c1b51eSKate Stone template <typename T, typename std::enable_if< 84b9c1b51eSKate Stone std::is_integral<T>::value && 8575930019STodd Fiala std::is_unsigned<T>::value>::type * = nullptr> JSONNumber(T u)86b9c1b51eSKate Stone explicit JSONNumber(T u) 87b9c1b51eSKate Stone : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { 8875930019STodd Fiala m_data.m_unsigned = u; 8975930019STodd Fiala } 9075930019STodd Fiala 9175930019STodd Fiala template <typename T, 9275930019STodd Fiala typename std::enable_if<std::is_integral<T>::value && 9375930019STodd Fiala std::is_signed<T>::value>::type * = nullptr> JSONNumber(T s)94b9c1b51eSKate Stone explicit JSONNumber(T s) 95b9c1b51eSKate Stone : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { 9675930019STodd Fiala m_data.m_signed = s; 9775930019STodd Fiala } 9875930019STodd Fiala 99b9c1b51eSKate Stone template <typename T, typename std::enable_if< 100b9c1b51eSKate Stone std::is_floating_point<T>::value>::type * = nullptr> JSONNumber(T d)101b9c1b51eSKate Stone explicit JSONNumber(T d) 102b9c1b51eSKate Stone : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { 10375930019STodd Fiala m_data.m_double = d; 10475930019STodd Fiala } 10575930019STodd Fiala 10675930019STodd Fiala ~JSONNumber() override = default; 10775930019STodd Fiala 10875930019STodd Fiala JSONNumber(const JSONNumber &s) = delete; 109b9c1b51eSKate Stone JSONNumber &operator=(const JSONNumber &s) = delete; 11075930019STodd Fiala 111b9c1b51eSKate Stone void Write(std::ostream &s) override; 11275930019STodd Fiala 113b9c1b51eSKate Stone uint64_t GetAsUnsigned() const; 11475930019STodd Fiala 115b9c1b51eSKate Stone int64_t GetAsSigned() const; 11675930019STodd Fiala 117b9c1b51eSKate Stone double GetAsDouble() const; 11875930019STodd Fiala classof(const JSONValue * V)119b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 12075930019STodd Fiala return V->GetKind() == JSONValue::Kind::Number; 12175930019STodd Fiala } 12275930019STodd Fiala 12375930019STodd Fiala private: 124b9c1b51eSKate Stone enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; 12575930019STodd Fiala 126b9c1b51eSKate Stone union { 12775930019STodd Fiala uint64_t m_unsigned; 12875930019STodd Fiala int64_t m_signed; 12975930019STodd Fiala double m_double; 13075930019STodd Fiala } m_data; 13175930019STodd Fiala }; 13275930019STodd Fiala 133b9c1b51eSKate Stone class JSONTrue : public JSONValue { 13475930019STodd Fiala public: 13575930019STodd Fiala JSONTrue(); 13675930019STodd Fiala 13775930019STodd Fiala JSONTrue(const JSONTrue &s) = delete; 138b9c1b51eSKate Stone JSONTrue &operator=(const JSONTrue &s) = delete; 13975930019STodd Fiala 140b9c1b51eSKate Stone void Write(std::ostream &s) override; 14175930019STodd Fiala 14275930019STodd Fiala typedef std::shared_ptr<JSONTrue> SP; 14375930019STodd Fiala classof(const JSONValue * V)144b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 14575930019STodd Fiala return V->GetKind() == JSONValue::Kind::True; 14675930019STodd Fiala } 14775930019STodd Fiala 14875930019STodd Fiala ~JSONTrue() override = default; 14975930019STodd Fiala }; 15075930019STodd Fiala 151b9c1b51eSKate Stone class JSONFalse : public JSONValue { 15275930019STodd Fiala public: 15375930019STodd Fiala JSONFalse(); 15475930019STodd Fiala 15575930019STodd Fiala JSONFalse(const JSONFalse &s) = delete; 156b9c1b51eSKate Stone JSONFalse &operator=(const JSONFalse &s) = delete; 15775930019STodd Fiala 158b9c1b51eSKate Stone void Write(std::ostream &s) override; 15975930019STodd Fiala 16075930019STodd Fiala typedef std::shared_ptr<JSONFalse> SP; 16175930019STodd Fiala classof(const JSONValue * V)162b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 16375930019STodd Fiala return V->GetKind() == JSONValue::Kind::False; 16475930019STodd Fiala } 16575930019STodd Fiala 16675930019STodd Fiala ~JSONFalse() override = default; 16775930019STodd Fiala }; 16875930019STodd Fiala 169b9c1b51eSKate Stone class JSONNull : public JSONValue { 17075930019STodd Fiala public: 17175930019STodd Fiala JSONNull(); 17275930019STodd Fiala 17375930019STodd Fiala JSONNull(const JSONNull &s) = delete; 174b9c1b51eSKate Stone JSONNull &operator=(const JSONNull &s) = delete; 17575930019STodd Fiala 176b9c1b51eSKate Stone void Write(std::ostream &s) override; 17775930019STodd Fiala 17875930019STodd Fiala typedef std::shared_ptr<JSONNull> SP; 17975930019STodd Fiala classof(const JSONValue * V)180b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 18175930019STodd Fiala return V->GetKind() == JSONValue::Kind::Null; 18275930019STodd Fiala } 18375930019STodd Fiala 18475930019STodd Fiala ~JSONNull() override = default; 18575930019STodd Fiala }; 18675930019STodd Fiala 187b9c1b51eSKate Stone class JSONObject : public JSONValue { 18875930019STodd Fiala public: 18975930019STodd Fiala JSONObject(); 19075930019STodd Fiala 19175930019STodd Fiala JSONObject(const JSONObject &s) = delete; 192b9c1b51eSKate Stone JSONObject &operator=(const JSONObject &s) = delete; 19375930019STodd Fiala 194b9c1b51eSKate Stone void Write(std::ostream &s) override; 19575930019STodd Fiala 19675930019STodd Fiala typedef std::shared_ptr<JSONObject> SP; 19775930019STodd Fiala classof(const JSONValue * V)198b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 19975930019STodd Fiala return V->GetKind() == JSONValue::Kind::Object; 20075930019STodd Fiala } 20175930019STodd Fiala 202b9c1b51eSKate Stone bool SetObject(const std::string &key, JSONValue::SP value); 20375930019STodd Fiala 204b9c1b51eSKate Stone JSONValue::SP GetObject(const std::string &key) const; 20575930019STodd Fiala 20675930019STodd Fiala /// Return keyed value as bool 20775930019STodd Fiala /// 208f05b42e9SAdrian Prantl /// \param[in] key 20975930019STodd Fiala /// The value of the key to lookup 21075930019STodd Fiala /// 211f05b42e9SAdrian Prantl /// \param[out] value 21275930019STodd Fiala /// The value of the key as a bool. Undefined if the key doesn't 21375930019STodd Fiala /// exist or if the key is not either true or false. 21475930019STodd Fiala /// 215f05b42e9SAdrian Prantl /// \return 21675930019STodd Fiala /// true if the key existed as was a bool value; false otherwise. 21775930019STodd Fiala /// Note the return value is *not* the value of the bool, use 21875930019STodd Fiala /// \b value for that. 219b9c1b51eSKate Stone bool GetObjectAsBool(const std::string &key, bool &value) const; 22075930019STodd Fiala 221b9c1b51eSKate Stone bool GetObjectAsString(const std::string &key, std::string &value) const; 22275930019STodd Fiala 22375930019STodd Fiala ~JSONObject() override = default; 22475930019STodd Fiala 22575930019STodd Fiala private: 22675930019STodd Fiala typedef std::map<std::string, JSONValue::SP> Map; 22775930019STodd Fiala typedef Map::iterator Iterator; 22875930019STodd Fiala Map m_elements; 22975930019STodd Fiala }; 23075930019STodd Fiala 231b9c1b51eSKate Stone class JSONArray : public JSONValue { 23275930019STodd Fiala public: 23375930019STodd Fiala JSONArray(); 23475930019STodd Fiala 23575930019STodd Fiala JSONArray(const JSONArray &s) = delete; 236b9c1b51eSKate Stone JSONArray &operator=(const JSONArray &s) = delete; 23775930019STodd Fiala 238b9c1b51eSKate Stone void Write(std::ostream &s) override; 23975930019STodd Fiala 24075930019STodd Fiala typedef std::shared_ptr<JSONArray> SP; 24175930019STodd Fiala classof(const JSONValue * V)242b9c1b51eSKate Stone static bool classof(const JSONValue *V) { 24375930019STodd Fiala return V->GetKind() == JSONValue::Kind::Array; 24475930019STodd Fiala } 24575930019STodd Fiala 24675930019STodd Fiala private: 24775930019STodd Fiala typedef std::vector<JSONValue::SP> Vector; 24875930019STodd Fiala typedef Vector::iterator Iterator; 24975930019STodd Fiala typedef Vector::size_type Index; 25075930019STodd Fiala typedef Vector::size_type Size; 25175930019STodd Fiala 25275930019STodd Fiala public: 253b9c1b51eSKate Stone bool SetObject(Index i, JSONValue::SP value); 25475930019STodd Fiala 255b9c1b51eSKate Stone bool AppendObject(JSONValue::SP value); 25675930019STodd Fiala 257b9c1b51eSKate Stone JSONValue::SP GetObject(Index i); 25875930019STodd Fiala 259b9c1b51eSKate Stone Size GetNumElements(); 26075930019STodd Fiala 26175930019STodd Fiala ~JSONArray() override = default; 26275930019STodd Fiala 26375930019STodd Fiala Vector m_elements; 26475930019STodd Fiala }; 26575930019STodd Fiala 266b9c1b51eSKate Stone class JSONParser : public StdStringExtractor { 26775930019STodd Fiala public: 268b9c1b51eSKate Stone enum Token { 26975930019STodd Fiala Invalid, 27097206d57SZachary Turner Status, 27175930019STodd Fiala ObjectStart, 27275930019STodd Fiala ObjectEnd, 27375930019STodd Fiala ArrayStart, 27475930019STodd Fiala ArrayEnd, 27575930019STodd Fiala Comma, 27675930019STodd Fiala Colon, 27775930019STodd Fiala String, 27875930019STodd Fiala Integer, 27975930019STodd Fiala Float, 28075930019STodd Fiala True, 28175930019STodd Fiala False, 28275930019STodd Fiala Null, 28375930019STodd Fiala EndOfFile 28475930019STodd Fiala }; 28575930019STodd Fiala 28675930019STodd Fiala JSONParser(const char *cstr); 28775930019STodd Fiala 288b9c1b51eSKate Stone int GetEscapedChar(bool &was_escaped); 28975930019STodd Fiala 290b9c1b51eSKate Stone Token GetToken(std::string &value); 29175930019STodd Fiala 292b9c1b51eSKate Stone JSONValue::SP ParseJSONValue(); 29375930019STodd Fiala 29475930019STodd Fiala protected: 29510b85143SAlex Cameron JSONValue::SP ParseJSONValue(const std::string &value, const Token &token); 29610b85143SAlex Cameron 297b9c1b51eSKate Stone JSONValue::SP ParseJSONObject(); 29875930019STodd Fiala 299b9c1b51eSKate Stone JSONValue::SP ParseJSONArray(); 30075930019STodd Fiala }; 30175930019STodd Fiala 302cdc514e4SJonas Devlieghere #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H 303