Coverage Report

Created: 2024-11-21 14:31

/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 <string>
22
23
#include "gutil/ref_counted.h"
24
25
namespace doris {
26
27
// A wrapper around rapidjson Value objects, to simplify usage.
28
// Intended solely for building json objects, not writing/parsing.
29
//
30
// Simplifies code like this:
31
//
32
//   rapidjson::Document d;
33
//   rapidjson::Value v;
34
//   v.SetObject();
35
//   rapidjson::Value list;
36
//   list.SetArray();
37
//   v.AddMember("list", list, d.GetAllocator());
38
//   v["list"].PushBack(rapidjson::Value().SetString("element"), d.GetAllocator());
39
//
40
// To this:
41
//
42
//   EasyJson ej;
43
//   ej["list"][0] = "element";
44
//
45
// Client code should build objects as demonstrated above,
46
// then call EasyJson::value() to obtain a reference to the
47
// built rapidjson Value.
48
class EasyJson {
49
public:
50
    // Used for initializing EasyJson's with complex types.
51
    // For example:
52
    //
53
    //  EasyJson array;
54
    //  EasyJson nested = array.PushBack(EasyJson::kObject);
55
    //  nested["attr"] = "val";
56
    //  // array = [ { "attr": "val" } ]
57
    enum ComplexTypeInitializer { kObject, kArray };
58
59
    EasyJson();
60
    // Initializes the EasyJson object with the given type.
61
    explicit EasyJson(ComplexTypeInitializer type);
62
27
    ~EasyJson() = default;
63
64
    // Returns the child EasyJson associated with key.
65
    //
66
    // Note: this method can mutate the EasyJson object
67
    // as follows:
68
    //
69
    // If this EasyJson's underlying Value is not an object
70
    // (i.e. !this->value().IsObject()), then its Value is
71
    // coerced to an object, overwriting the old Value.
72
    // If the given key does not exist, a Null-valued
73
    // EasyJson associated with key is created.
74
    EasyJson Get(const std::string& key);
75
76
    // Returns the child EasyJson at index.
77
    //
78
    // Note: this method can mutate the EasyJson object
79
    // as follows:
80
    //
81
    // If this EasyJson's underlying Value is not an array
82
    // (i.e. !this->value().IsArray()), then its Value is
83
    // coerced to an array, overwriting the old Value.
84
    // If index >= this->value().Size(), then the underlying
85
    // array's size is increased to index + 1 (new indices
86
    // are filled with Null values).
87
    EasyJson Get(int index);
88
89
    // Same as Get(key).
90
    EasyJson operator[](const std::string& key);
91
    // Same as Get(index).
92
    EasyJson operator[](int index);
93
94
    // Sets the underlying Value equal to val.
95
    // Returns a reference to the object itself.
96
    //
97
    // 'val' can be a bool, int32_t, int64_t, double,
98
    // char*, string, or ComplexTypeInitializer.
99
    EasyJson& operator=(const std::string& val);
100
    template <typename T>
101
    EasyJson& operator=(T val);
102
103
    // Sets the underlying Value to an object.
104
    // Returns a reference to the object itself.
105
    //
106
    // i.e. after calling SetObject(),
107
    // value().IsObject() == true
108
    EasyJson& SetObject();
109
    // Sets the underlying Value to an array.
110
    // Returns a reference to the object itself.
111
    //
112
    // i.e. after calling SetArray(),
113
    // value().IsArray() == true
114
    EasyJson& SetArray();
115
116
    // Associates val with key.
117
    // Returns the child object.
118
    //
119
    // If this EasyJson's underlying Value is not an object
120
    // (i.e. !this->value().IsObject()), then its Value is
121
    // coerced to an object, overwriting the old Value.
122
    // If the given key does not exist, a new child entry
123
    // is created with the given value.
124
    EasyJson Set(const std::string& key, const std::string& val);
125
    template <typename T>
126
    EasyJson Set(const std::string& key, T val);
127
128
    // Stores val at index.
129
    // Returns the child object.
130
    //
131
    // If this EasyJson's underlying Value is not an array
132
    // (i.e. !this->value().IsArray()), then its Value is
133
    // coerced to an array, overwriting the old Value.
134
    // If index >= this->value().Size(), then the underlying
135
    // array's size is increased to index + 1 (new indices
136
    // are filled with Null values).
137
    EasyJson Set(int index, const std::string& val);
138
    template <typename T>
139
    EasyJson Set(int index, T val);
140
141
    // Appends val to the underlying array.
142
    // Returns a reference to the new child object.
143
    //
144
    // If this EasyJson's underlying Value is not an array
145
    // (i.e. !this->value().IsArray()), then its Value is
146
    // coerced to an array, overwriting the old Value.
147
    EasyJson PushBack(const std::string& val);
148
    template <typename T>
149
    EasyJson PushBack(T val);
150
151
    // Returns a reference to the underlying Value.
152
11
    rapidjson::Value& value() const { return *value_; }
153
154
    // Returns a string representation of the underlying json.
155
    std::string ToString() const;
156
157
private:
158
    // One instance of EasyJsonAllocator is shared among a root
159
    // EasyJson object and all of its descendants. The allocator
160
    // owns the underlying rapidjson Value, and a rapidjson
161
    // allocator (via a rapidjson::Document).
162
    class EasyJsonAllocator : public RefCounted<EasyJsonAllocator> {
163
    public:
164
5
        rapidjson::Value& value() { return value_; }
165
23
        rapidjson::Document::AllocatorType& allocator() { return value_.GetAllocator(); }
166
167
    private:
168
        friend class RefCounted<EasyJsonAllocator>;
169
5
        ~EasyJsonAllocator() = default;
170
171
        // The underlying rapidjson::Value object (Document is
172
        // a subclass of Value that has its own allocator).
173
        rapidjson::Document value_;
174
    };
175
176
    // Used to instantiate descendant objects.
177
    EasyJson(rapidjson::Value* value, scoped_refptr<EasyJsonAllocator> alloc);
178
179
    // One allocator is shared among an EasyJson object and
180
    // all of its descendants.
181
    scoped_refptr<EasyJsonAllocator> alloc_;
182
183
    // A pointer to the underlying Value in the object
184
    // tree owned by alloc_.
185
    rapidjson::Value* value_ = nullptr;
186
};
187
188
} // namespace doris