Coverage Report

Created: 2025-05-19 20:49

/root/doris/be/src/util/easy_json.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
#pragma once
18
19
#include <rapidjson/document.h>
20
21
#include <memory>
22
#include <string>
23
24
namespace doris {
25
26
// A wrapper around rapidjson Value objects, to simplify usage.
27
// Intended solely for building json objects, not writing/parsing.
28
//
29
// Simplifies code like this:
30
//
31
//   rapidjson::Document d;
32
//   rapidjson::Value v;
33
//   v.SetObject();
34
//   rapidjson::Value list;
35
//   list.SetArray();
36
//   v.AddMember("list", list, d.GetAllocator());
37
//   v["list"].PushBack(rapidjson::Value().SetString("element"), d.GetAllocator());
38
//
39
// To this:
40
//
41
//   EasyJson ej;
42
//   ej["list"][0] = "element";
43
//
44
// Client code should build objects as demonstrated above,
45
// then call EasyJson::value() to obtain a reference to the
46
// built rapidjson Value.
47
class EasyJson {
48
public:
49
    // Used for initializing EasyJson's with complex types.
50
    // For example:
51
    //
52
    //  EasyJson array;
53
    //  EasyJson nested = array.PushBack(EasyJson::kObject);
54
    //  nested["attr"] = "val";
55
    //  // array = [ { "attr": "val" } ]
56
    enum ComplexTypeInitializer { kObject, kArray };
57
58
    EasyJson();
59
    // Initializes the EasyJson object with the given type.
60
    explicit EasyJson(ComplexTypeInitializer type);
61
27
    ~EasyJson() = default;
62
63
    // Returns the child EasyJson associated with key.
64
    //
65
    // Note: this method can mutate the EasyJson object
66
    // as follows:
67
    //
68
    // If this EasyJson's underlying Value is not an object
69
    // (i.e. !this->value().IsObject()), then its Value is
70
    // coerced to an object, overwriting the old Value.
71
    // If the given key does not exist, a Null-valued
72
    // EasyJson associated with key is created.
73
    EasyJson Get(const std::string& key);
74
75
    // Returns the child EasyJson at index.
76
    //
77
    // Note: this method can mutate the EasyJson object
78
    // as follows:
79
    //
80
    // If this EasyJson's underlying Value is not an array
81
    // (i.e. !this->value().IsArray()), then its Value is
82
    // coerced to an array, overwriting the old Value.
83
    // If index >= this->value().Size(), then the underlying
84
    // array's size is increased to index + 1 (new indices
85
    // are filled with Null values).
86
    EasyJson Get(int index);
87
88
    // Same as Get(key).
89
    EasyJson operator[](const std::string& key);
90
    // Same as Get(index).
91
    EasyJson operator[](int index);
92
93
    // Sets the underlying Value equal to val.
94
    // Returns a reference to the object itself.
95
    //
96
    // 'val' can be a bool, int32_t, int64_t, double,
97
    // char*, string, or ComplexTypeInitializer.
98
    EasyJson& operator=(const std::string& val);
99
    template <typename T>
100
    EasyJson& operator=(T val);
101
102
    // Sets the underlying Value to an object.
103
    // Returns a reference to the object itself.
104
    //
105
    // i.e. after calling SetObject(),
106
    // value().IsObject() == true
107
    EasyJson& SetObject();
108
    // Sets the underlying Value to an array.
109
    // Returns a reference to the object itself.
110
    //
111
    // i.e. after calling SetArray(),
112
    // value().IsArray() == true
113
    EasyJson& SetArray();
114
115
    // Associates val with key.
116
    // Returns the child object.
117
    //
118
    // If this EasyJson's underlying Value is not an object
119
    // (i.e. !this->value().IsObject()), then its Value is
120
    // coerced to an object, overwriting the old Value.
121
    // If the given key does not exist, a new child entry
122
    // is created with the given value.
123
    EasyJson Set(const std::string& key, const std::string& val);
124
    template <typename T>
125
    EasyJson Set(const std::string& key, T val);
126
127
    // Stores val at index.
128
    // Returns the child object.
129
    //
130
    // If this EasyJson's underlying Value is not an array
131
    // (i.e. !this->value().IsArray()), then its Value is
132
    // coerced to an array, overwriting the old Value.
133
    // If index >= this->value().Size(), then the underlying
134
    // array's size is increased to index + 1 (new indices
135
    // are filled with Null values).
136
    EasyJson Set(int index, const std::string& val);
137
    template <typename T>
138
    EasyJson Set(int index, T val);
139
140
    // Appends val to the underlying array.
141
    // Returns a reference to the new child object.
142
    //
143
    // If this EasyJson's underlying Value is not an array
144
    // (i.e. !this->value().IsArray()), then its Value is
145
    // coerced to an array, overwriting the old Value.
146
    EasyJson PushBack(const std::string& val);
147
    template <typename T>
148
    EasyJson PushBack(T val);
149
150
    // Returns a reference to the underlying Value.
151
11
    rapidjson::Value& value() const { return *value_; }
152
153
    // Returns a string representation of the underlying json.
154
    std::string ToString() const;
155
156
private:
157
    // One instance of EasyJsonAllocator is shared among a root
158
    // EasyJson object and all of its descendants. The allocator
159
    // owns the underlying rapidjson Value, and a rapidjson
160
    // allocator (via a rapidjson::Document).
161
    class EasyJsonAllocator {
162
    public:
163
5
        rapidjson::Value& value() { return value_; }
164
23
        rapidjson::Document::AllocatorType& allocator() { return value_.GetAllocator(); }
165
166
    private:
167
        // The underlying rapidjson::Value object (Document is
168
        // a subclass of Value that has its own allocator).
169
        rapidjson::Document value_;
170
    };
171
172
    // Used to instantiate descendant objects.
173
    EasyJson(rapidjson::Value* value, std::shared_ptr<EasyJsonAllocator> alloc);
174
175
    // One allocator is shared among an EasyJson object and
176
    // all of its descendants.
177
    std::shared_ptr<EasyJsonAllocator> alloc_;
178
179
    // A pointer to the underlying Value in the object
180
    // tree owned by alloc_.
181
    rapidjson::Value* value_ = nullptr;
182
};
183
184
} // namespace doris