1
#pragma once
2

            
3
#include <cstdint>
4
#include <functional>
5
#include <memory>
6
#include <string>
7
#include <vector>
8

            
9
#include "envoy/common/exception.h"
10
#include "envoy/common/pure.h"
11

            
12
#include "source/common/common/statusor.h"
13

            
14
#include "absl/types/variant.h"
15

            
16
namespace Envoy {
17
namespace Json {
18
class Object;
19

            
20
using ObjectSharedPtr = std::shared_ptr<Object>;
21

            
22
// @return false if immediate exit from iteration required.
23
using ObjectCallback = std::function<bool(const std::string&, const Object&)>;
24

            
25
/**
26
 * Exception thrown when a JSON error occurs.
27
 */
28
class Exception : public EnvoyException {
29
public:
30
  Exception(const std::string& message) : EnvoyException(message) {}
31
};
32

            
33
using ValueType = absl::variant<bool, int64_t, double, std::string>;
34

            
35
/**
36
 * Wraps an individual JSON node.
37
 */
38
class Object {
39
public:
40
44455
  virtual ~Object() = default;
41

            
42
  /**
43
   * Convert a generic object into an array of objects. This is useful for dealing
44
   * with arrays of arrays.
45
   * @return std::vector<ObjectSharedPtr> the converted object.
46
   */
47
  virtual absl::StatusOr<std::vector<ObjectSharedPtr>> asObjectArray() const PURE;
48

            
49
  /**
50
   * Get a bool, integer, double or string value by name.
51
   * @param name supplies the key name.
52
   * @return bool the value.
53
   */
54
  virtual absl::StatusOr<ValueType> getValue(const std::string& name) const PURE;
55

            
56
  /**
57
   * Get a boolean value by name.
58
   * @param name supplies the key name.
59
   * @return bool the value.
60
   */
61
  virtual absl::StatusOr<bool> getBoolean(const std::string& name) const PURE;
62

            
63
  /**
64
   * Get a boolean value by name.
65
   * @param name supplies the key name.
66
   * @param default_value supplies the value to return if the name does not exist.
67
   * @return bool the value.
68
   */
69
  virtual absl::StatusOr<bool> getBoolean(const std::string& name, bool default_value) const PURE;
70

            
71
  /**
72
   * Get an integer value by name.
73
   * @param name supplies the key name.
74
   * @return int64_t the value.
75
   */
76
  virtual absl::StatusOr<int64_t> getInteger(const std::string& name) const PURE;
77

            
78
  /**
79
   * Get an integer value by name or return a default if name does not exist.
80
   * @param name supplies the key name.
81
   * @param default_value supplies the value to return if name does not exist.
82
   * @return int64_t the value.
83
   */
84
  virtual absl::StatusOr<int64_t> getInteger(const std::string& name,
85
                                             int64_t default_value) const PURE;
86

            
87
  /**
88
   * Get a sub-object by name.
89
   * @param name supplies the key name.
90
   * @param allow_empty supplies whether to return an empty object if the key does not
91
   * exist.
92
   * @return ObjectObjectSharedPtr the sub-object.
93
   */
94
  virtual absl::StatusOr<ObjectSharedPtr> getObject(const std::string& name,
95
                                                    bool allow_empty = false) const PURE;
96

            
97
  /**
98
   * Determine if an object has type Object.
99
   * @return bool is the object an Object?
100
   */
101
  virtual bool isObject() const PURE;
102

            
103
  /**
104
   * Determine if an object has type Array.
105
   * @return bool is the object an Array?
106
   */
107
  virtual bool isArray() const PURE;
108

            
109
  /**
110
   * Get an array by name.
111
   * @param name supplies the key name.
112
   * @param allow_empty specifies whether to return an empty array if the key does not exist.
113
   * @return std::vector<ObjectSharedPtr> the array of JSON  objects.
114
   */
115
  virtual absl::StatusOr<std::vector<ObjectSharedPtr>>
116
  getObjectArray(const std::string& name, bool allow_empty = false) const PURE;
117

            
118
  /**
119
   * Get a string value by name.
120
   * @param name supplies the key name.
121
   * @return std::string the value.
122
   */
123
  virtual absl::StatusOr<std::string> getString(const std::string& name) const PURE;
124

            
125
  /**
126
   * Get a string value by name or return a default if name does not exist.
127
   * @param name supplies the key name.
128
   * @param default_value supplies the value to return if name does not exist.
129
   * @return std::string the value.
130
   */
131
  virtual absl::StatusOr<std::string> getString(const std::string& name,
132
                                                const std::string& default_value) const PURE;
133

            
134
  /**
135
   * Get a string array by name.
136
   * @param name supplies the key name.
137
   * @param allow_empty specifies whether to return an empty array if the key does not exist.
138
   * @return std::vector<std::string> the array of strings.
139
   */
140
  virtual absl::StatusOr<std::vector<std::string>>
141
  getStringArray(const std::string& name, bool allow_empty = false) const PURE;
142

            
143
  /**
144
   * Get a double value by name.
145
   * @param name supplies the key name.
146
   * @return double the value.
147
   */
148
  virtual absl::StatusOr<double> getDouble(const std::string& name) const PURE;
149

            
150
  /**
151
   * Get a double value by name.
152
   * @param name supplies the key name.
153
   * @param default_value supplies the value to return if name does not exist.
154
   * @return double the value.
155
   */
156
  virtual absl::StatusOr<double> getDouble(const std::string& name,
157
                                           double default_value) const PURE;
158

            
159
  /**
160
   * @return a hash of the JSON object.
161
   * Per RFC 7159:
162
   *    An object is an unordered collection of zero or more name/value
163
   *    pairs, where a name is a string and a value is a string, number,
164
   *    boolean, null, object, or array.
165
   * Objects with fields in different orders are equivalent and produce the same hash.
166
   * It does not consider white space that was originally in the parsed JSON.
167
   */
168
  virtual uint64_t hash() const PURE;
169

            
170
  /**
171
   * Iterate over key-value pairs in an Object and call callback on each pair.
172
   */
173
  virtual absl::Status iterate(const ObjectCallback& callback) const PURE;
174

            
175
  /**
176
   * @return TRUE if the Object contains the key.
177
   * @param name supplies the key name to lookup.
178
   */
179
  virtual bool hasObject(const std::string& name) const PURE;
180

            
181
  /**
182
   * Validates JSON object against passed in schema.
183
   * @param schema supplies the schema in string format. A Json::Exception will be thrown if
184
   *        the JSON object doesn't conform to the supplied schema or the schema itself is not
185
   *        valid.
186
   */
187
  virtual void validateSchema(const std::string& schema) const PURE;
188

            
189
  /**
190
   * @return the value of the object as a string (where the object is a string).
191
   */
192
  virtual absl::StatusOr<std::string> asString() const PURE;
193

            
194
  /**
195
   * @return the JSON string representation of the object.
196
   */
197
  virtual std::string asJsonString() const PURE;
198

            
199
  /**
200
   * @return true if the JSON object is empty;
201
   */
202
  virtual bool empty() const PURE;
203
};
204

            
205
} // namespace Json
206
} // namespace Envoy