xref: /aosp_15_r20/external/grpc-grpc/include/grpc/support/json.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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