1*cc02d7e2SAndroid Build Coastguard Worker // 2*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors. 3*cc02d7e2SAndroid Build Coastguard Worker // 4*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 5*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 6*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at 7*cc02d7e2SAndroid Build Coastguard Worker // 8*cc02d7e2SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 9*cc02d7e2SAndroid Build Coastguard Worker // 10*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 11*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 12*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 14*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License. 15*cc02d7e2SAndroid Build Coastguard Worker // 16*cc02d7e2SAndroid Build Coastguard Worker 17*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPC_SUPPORT_JSON_H 18*cc02d7e2SAndroid Build Coastguard Worker #define GRPC_SUPPORT_JSON_H 19*cc02d7e2SAndroid Build Coastguard Worker 20*cc02d7e2SAndroid Build Coastguard Worker #include <stdint.h> 21*cc02d7e2SAndroid Build Coastguard Worker 22*cc02d7e2SAndroid Build Coastguard Worker #include <map> 23*cc02d7e2SAndroid Build Coastguard Worker #include <string> 24*cc02d7e2SAndroid Build Coastguard Worker #include <utility> 25*cc02d7e2SAndroid Build Coastguard Worker #include <vector> 26*cc02d7e2SAndroid Build Coastguard Worker 27*cc02d7e2SAndroid Build Coastguard Worker #include "absl/strings/str_cat.h" 28*cc02d7e2SAndroid Build Coastguard Worker #include "absl/types/variant.h" 29*cc02d7e2SAndroid Build Coastguard Worker 30*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/port_platform.h> 31*cc02d7e2SAndroid Build Coastguard Worker 32*cc02d7e2SAndroid Build Coastguard Worker namespace grpc_core { 33*cc02d7e2SAndroid Build Coastguard Worker namespace experimental { 34*cc02d7e2SAndroid Build Coastguard Worker 35*cc02d7e2SAndroid Build Coastguard Worker // A JSON value, which can be any one of null, boolean, number, string, 36*cc02d7e2SAndroid Build Coastguard Worker // object, or array. 37*cc02d7e2SAndroid Build Coastguard Worker class Json { 38*cc02d7e2SAndroid Build Coastguard Worker public: 39*cc02d7e2SAndroid Build Coastguard Worker // The JSON type. 40*cc02d7e2SAndroid Build Coastguard Worker enum class Type { 41*cc02d7e2SAndroid Build Coastguard Worker kNull, // No payload. Default type when using the zero-arg ctor. 42*cc02d7e2SAndroid Build Coastguard Worker kBoolean, // Use boolean() for payload. 43*cc02d7e2SAndroid Build Coastguard Worker kNumber, // Numbers are stored in string form to avoid precision 44*cc02d7e2SAndroid Build Coastguard Worker // and integer capacity issues. Use string() for payload. 45*cc02d7e2SAndroid Build Coastguard Worker kString, // Use string() for payload. 46*cc02d7e2SAndroid Build Coastguard Worker kObject, // Use object() for payload. 47*cc02d7e2SAndroid Build Coastguard Worker kArray, // Use array() for payload. 48*cc02d7e2SAndroid Build Coastguard Worker }; 49*cc02d7e2SAndroid Build Coastguard Worker 50*cc02d7e2SAndroid Build Coastguard Worker using Object = std::map<std::string, Json>; 51*cc02d7e2SAndroid Build Coastguard Worker using Array = std::vector<Json>; 52*cc02d7e2SAndroid Build Coastguard Worker 53*cc02d7e2SAndroid Build Coastguard Worker // Factory method for kBoolean. FromBool(bool b)54*cc02d7e2SAndroid Build Coastguard Worker static Json FromBool(bool b) { 55*cc02d7e2SAndroid Build Coastguard Worker Json json; 56*cc02d7e2SAndroid Build Coastguard Worker json.value_ = b; 57*cc02d7e2SAndroid Build Coastguard Worker return json; 58*cc02d7e2SAndroid Build Coastguard Worker } 59*cc02d7e2SAndroid Build Coastguard Worker 60*cc02d7e2SAndroid Build Coastguard Worker // Factory methods for kNumber. FromNumber(const std::string & str)61*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(const std::string& str) { 62*cc02d7e2SAndroid Build Coastguard Worker Json json; 63*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{str}; 64*cc02d7e2SAndroid Build Coastguard Worker return json; 65*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(const char * str)66*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(const char* str) { 67*cc02d7e2SAndroid Build Coastguard Worker Json json; 68*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{std::string(str)}; 69*cc02d7e2SAndroid Build Coastguard Worker return json; 70*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(std::string && str)71*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(std::string&& str) { 72*cc02d7e2SAndroid Build Coastguard Worker Json json; 73*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{std::move(str)}; 74*cc02d7e2SAndroid Build Coastguard Worker return json; 75*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(int32_t value)76*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(int32_t value) { 77*cc02d7e2SAndroid Build Coastguard Worker Json json; 78*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{absl::StrCat(value)}; 79*cc02d7e2SAndroid Build Coastguard Worker return json; 80*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(uint32_t value)81*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(uint32_t value) { 82*cc02d7e2SAndroid Build Coastguard Worker Json json; 83*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{absl::StrCat(value)}; 84*cc02d7e2SAndroid Build Coastguard Worker return json; 85*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(int64_t value)86*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(int64_t value) { 87*cc02d7e2SAndroid Build Coastguard Worker Json json; 88*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{absl::StrCat(value)}; 89*cc02d7e2SAndroid Build Coastguard Worker return json; 90*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(uint64_t value)91*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(uint64_t value) { 92*cc02d7e2SAndroid Build Coastguard Worker Json json; 93*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{absl::StrCat(value)}; 94*cc02d7e2SAndroid Build Coastguard Worker return json; 95*cc02d7e2SAndroid Build Coastguard Worker } FromNumber(double value)96*cc02d7e2SAndroid Build Coastguard Worker static Json FromNumber(double value) { 97*cc02d7e2SAndroid Build Coastguard Worker Json json; 98*cc02d7e2SAndroid Build Coastguard Worker json.value_ = NumberValue{absl::StrCat(value)}; 99*cc02d7e2SAndroid Build Coastguard Worker return json; 100*cc02d7e2SAndroid Build Coastguard Worker } 101*cc02d7e2SAndroid Build Coastguard Worker 102*cc02d7e2SAndroid Build Coastguard Worker // Factory methods for kString. FromString(const std::string & str)103*cc02d7e2SAndroid Build Coastguard Worker static Json FromString(const std::string& str) { 104*cc02d7e2SAndroid Build Coastguard Worker Json json; 105*cc02d7e2SAndroid Build Coastguard Worker json.value_ = str; 106*cc02d7e2SAndroid Build Coastguard Worker return json; 107*cc02d7e2SAndroid Build Coastguard Worker } FromString(const char * str)108*cc02d7e2SAndroid Build Coastguard Worker static Json FromString(const char* str) { 109*cc02d7e2SAndroid Build Coastguard Worker Json json; 110*cc02d7e2SAndroid Build Coastguard Worker json.value_ = std::string(str); 111*cc02d7e2SAndroid Build Coastguard Worker return json; 112*cc02d7e2SAndroid Build Coastguard Worker } FromString(std::string && str)113*cc02d7e2SAndroid Build Coastguard Worker static Json FromString(std::string&& str) { 114*cc02d7e2SAndroid Build Coastguard Worker Json json; 115*cc02d7e2SAndroid Build Coastguard Worker json.value_ = std::move(str); 116*cc02d7e2SAndroid Build Coastguard Worker return json; 117*cc02d7e2SAndroid Build Coastguard Worker } 118*cc02d7e2SAndroid Build Coastguard Worker 119*cc02d7e2SAndroid Build Coastguard Worker // Factory methods for kObject. FromObject(const Object & object)120*cc02d7e2SAndroid Build Coastguard Worker static Json FromObject(const Object& object) { 121*cc02d7e2SAndroid Build Coastguard Worker Json json; 122*cc02d7e2SAndroid Build Coastguard Worker json.value_ = object; 123*cc02d7e2SAndroid Build Coastguard Worker return json; 124*cc02d7e2SAndroid Build Coastguard Worker } FromObject(Object && object)125*cc02d7e2SAndroid Build Coastguard Worker static Json FromObject(Object&& object) { 126*cc02d7e2SAndroid Build Coastguard Worker Json json; 127*cc02d7e2SAndroid Build Coastguard Worker json.value_ = std::move(object); 128*cc02d7e2SAndroid Build Coastguard Worker return json; 129*cc02d7e2SAndroid Build Coastguard Worker } 130*cc02d7e2SAndroid Build Coastguard Worker 131*cc02d7e2SAndroid Build Coastguard Worker // Factory methods for kArray. FromArray(const Array & array)132*cc02d7e2SAndroid Build Coastguard Worker static Json FromArray(const Array& array) { 133*cc02d7e2SAndroid Build Coastguard Worker Json json; 134*cc02d7e2SAndroid Build Coastguard Worker json.value_ = array; 135*cc02d7e2SAndroid Build Coastguard Worker return json; 136*cc02d7e2SAndroid Build Coastguard Worker } FromArray(Array && array)137*cc02d7e2SAndroid Build Coastguard Worker static Json FromArray(Array&& array) { 138*cc02d7e2SAndroid Build Coastguard Worker Json json; 139*cc02d7e2SAndroid Build Coastguard Worker json.value_ = std::move(array); 140*cc02d7e2SAndroid Build Coastguard Worker return json; 141*cc02d7e2SAndroid Build Coastguard Worker } 142*cc02d7e2SAndroid Build Coastguard Worker 143*cc02d7e2SAndroid Build Coastguard Worker Json() = default; 144*cc02d7e2SAndroid Build Coastguard Worker 145*cc02d7e2SAndroid Build Coastguard Worker // Copyable. 146*cc02d7e2SAndroid Build Coastguard Worker Json(const Json& other) = default; 147*cc02d7e2SAndroid Build Coastguard Worker Json& operator=(const Json& other) = default; 148*cc02d7e2SAndroid Build Coastguard Worker 149*cc02d7e2SAndroid Build Coastguard Worker // Moveable. Json(Json && other)150*cc02d7e2SAndroid Build Coastguard Worker Json(Json&& other) noexcept : value_(std::move(other.value_)) { 151*cc02d7e2SAndroid Build Coastguard Worker other.value_ = absl::monostate(); 152*cc02d7e2SAndroid Build Coastguard Worker } 153*cc02d7e2SAndroid Build Coastguard Worker Json& operator=(Json&& other) noexcept { 154*cc02d7e2SAndroid Build Coastguard Worker value_ = std::move(other.value_); 155*cc02d7e2SAndroid Build Coastguard Worker other.value_ = absl::monostate(); 156*cc02d7e2SAndroid Build Coastguard Worker return *this; 157*cc02d7e2SAndroid Build Coastguard Worker } 158*cc02d7e2SAndroid Build Coastguard Worker 159*cc02d7e2SAndroid Build Coastguard Worker // Returns the JSON type. type()160*cc02d7e2SAndroid Build Coastguard Worker Type type() const { 161*cc02d7e2SAndroid Build Coastguard Worker struct ValueFunctor { 162*cc02d7e2SAndroid Build Coastguard Worker Json::Type operator()(const absl::monostate&) { return Type::kNull; } 163*cc02d7e2SAndroid Build Coastguard Worker Json::Type operator()(bool) { return Type::kBoolean; } 164*cc02d7e2SAndroid Build Coastguard Worker Json::Type operator()(const NumberValue&) { return Type::kNumber; } 165*cc02d7e2SAndroid Build Coastguard Worker Json::Type operator()(const std::string&) { return Type::kString; } 166*cc02d7e2SAndroid Build Coastguard Worker Json::Type operator()(const Object&) { return Type::kObject; } 167*cc02d7e2SAndroid Build Coastguard Worker Json::Type operator()(const Array&) { return Type::kArray; } 168*cc02d7e2SAndroid Build Coastguard Worker }; 169*cc02d7e2SAndroid Build Coastguard Worker return absl::visit(ValueFunctor(), value_); 170*cc02d7e2SAndroid Build Coastguard Worker } 171*cc02d7e2SAndroid Build Coastguard Worker 172*cc02d7e2SAndroid Build Coastguard Worker // Payload accessor for kBoolean. 173*cc02d7e2SAndroid Build Coastguard Worker // Must not be called for other types. boolean()174*cc02d7e2SAndroid Build Coastguard Worker bool boolean() const { return absl::get<bool>(value_); } 175*cc02d7e2SAndroid Build Coastguard Worker 176*cc02d7e2SAndroid Build Coastguard Worker // Payload accessor for kNumber or kString. 177*cc02d7e2SAndroid Build Coastguard Worker // Must not be called for other types. string()178*cc02d7e2SAndroid Build Coastguard Worker const std::string& string() const { 179*cc02d7e2SAndroid Build Coastguard Worker const NumberValue* num = absl::get_if<NumberValue>(&value_); 180*cc02d7e2SAndroid Build Coastguard Worker if (num != nullptr) return num->value; 181*cc02d7e2SAndroid Build Coastguard Worker return absl::get<std::string>(value_); 182*cc02d7e2SAndroid Build Coastguard Worker } 183*cc02d7e2SAndroid Build Coastguard Worker 184*cc02d7e2SAndroid Build Coastguard Worker // Payload accessor for kObject. 185*cc02d7e2SAndroid Build Coastguard Worker // Must not be called for other types. object()186*cc02d7e2SAndroid Build Coastguard Worker const Object& object() const { return absl::get<Object>(value_); } 187*cc02d7e2SAndroid Build Coastguard Worker 188*cc02d7e2SAndroid Build Coastguard Worker // Payload accessor for kArray. 189*cc02d7e2SAndroid Build Coastguard Worker // Must not be called for other types. array()190*cc02d7e2SAndroid Build Coastguard Worker const Array& array() const { return absl::get<Array>(value_); } 191*cc02d7e2SAndroid Build Coastguard Worker 192*cc02d7e2SAndroid Build Coastguard Worker bool operator==(const Json& other) const { return value_ == other.value_; } 193*cc02d7e2SAndroid Build Coastguard Worker bool operator!=(const Json& other) const { return !(*this == other); } 194*cc02d7e2SAndroid Build Coastguard Worker 195*cc02d7e2SAndroid Build Coastguard Worker private: 196*cc02d7e2SAndroid Build Coastguard Worker struct NumberValue { 197*cc02d7e2SAndroid Build Coastguard Worker std::string value; 198*cc02d7e2SAndroid Build Coastguard Worker 199*cc02d7e2SAndroid Build Coastguard Worker bool operator==(const NumberValue& other) const { 200*cc02d7e2SAndroid Build Coastguard Worker return value == other.value; 201*cc02d7e2SAndroid Build Coastguard Worker } 202*cc02d7e2SAndroid Build Coastguard Worker }; 203*cc02d7e2SAndroid Build Coastguard Worker using Value = absl::variant<absl::monostate, // kNull 204*cc02d7e2SAndroid Build Coastguard Worker bool, // kBoolean 205*cc02d7e2SAndroid Build Coastguard Worker NumberValue, // kNumber 206*cc02d7e2SAndroid Build Coastguard Worker std::string, // kString 207*cc02d7e2SAndroid Build Coastguard Worker Object, // kObject 208*cc02d7e2SAndroid Build Coastguard Worker Array>; // kArray 209*cc02d7e2SAndroid Build Coastguard Worker Json(Value value)210*cc02d7e2SAndroid Build Coastguard Worker explicit Json(Value value) : value_(std::move(value)) {} 211*cc02d7e2SAndroid Build Coastguard Worker 212*cc02d7e2SAndroid Build Coastguard Worker Value value_; 213*cc02d7e2SAndroid Build Coastguard Worker }; 214*cc02d7e2SAndroid Build Coastguard Worker 215*cc02d7e2SAndroid Build Coastguard Worker } // namespace experimental 216*cc02d7e2SAndroid Build Coastguard Worker } // namespace grpc_core 217*cc02d7e2SAndroid Build Coastguard Worker 218*cc02d7e2SAndroid Build Coastguard Worker #endif // GRPC_SUPPORT_JSON_H 219