xref: /aosp_15_r20/external/cronet/base/values.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_VALUES_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_VALUES_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include <array>
12*6777b538SAndroid Build Coastguard Worker #include <initializer_list>
13*6777b538SAndroid Build Coastguard Worker #include <iosfwd>
14*6777b538SAndroid Build Coastguard Worker #include <iterator>
15*6777b538SAndroid Build Coastguard Worker #include <memory>
16*6777b538SAndroid Build Coastguard Worker #include <optional>
17*6777b538SAndroid Build Coastguard Worker #include <string>
18*6777b538SAndroid Build Coastguard Worker #include <utility>
19*6777b538SAndroid Build Coastguard Worker #include <vector>
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/bit_cast.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/containers/checked_iterators.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_map.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/base_tracing_forward.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/value_iterators.h"
31*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/types/variant.h"
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker namespace base {
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker // The `Value` class is a variant type can hold one of the following types:
36*6777b538SAndroid Build Coastguard Worker // - null
37*6777b538SAndroid Build Coastguard Worker // - bool
38*6777b538SAndroid Build Coastguard Worker // - int
39*6777b538SAndroid Build Coastguard Worker // - double
40*6777b538SAndroid Build Coastguard Worker // - string (internally UTF8-encoded)
41*6777b538SAndroid Build Coastguard Worker // - binary data (i.e. a blob)
42*6777b538SAndroid Build Coastguard Worker // - dictionary of string keys to `Value`s
43*6777b538SAndroid Build Coastguard Worker // - list of `Value`s
44*6777b538SAndroid Build Coastguard Worker //
45*6777b538SAndroid Build Coastguard Worker // With the exception of binary blobs, `Value` is intended to be the C++ version
46*6777b538SAndroid Build Coastguard Worker // of data types that can be represented in JSON.
47*6777b538SAndroid Build Coastguard Worker //
48*6777b538SAndroid Build Coastguard Worker // Warning: blob support may be removed in the future.
49*6777b538SAndroid Build Coastguard Worker //
50*6777b538SAndroid Build Coastguard Worker // ## Usage
51*6777b538SAndroid Build Coastguard Worker //
52*6777b538SAndroid Build Coastguard Worker // Do not use `Value` if a more specific type would be more appropriate.  For
53*6777b538SAndroid Build Coastguard Worker // example, a function that only accepts dictionary values should have a
54*6777b538SAndroid Build Coastguard Worker // `base::Value::Dict` parameter, not a `base::Value` parameter.
55*6777b538SAndroid Build Coastguard Worker //
56*6777b538SAndroid Build Coastguard Worker // Construction:
57*6777b538SAndroid Build Coastguard Worker //
58*6777b538SAndroid Build Coastguard Worker // `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
59*6777b538SAndroid Build Coastguard Worker // (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
60*6777b538SAndroid Build Coastguard Worker // `Value::Dict`, and `Value::List`.
61*6777b538SAndroid Build Coastguard Worker //
62*6777b538SAndroid Build Coastguard Worker // Copying:
63*6777b538SAndroid Build Coastguard Worker //
64*6777b538SAndroid Build Coastguard Worker // `Value` does not support C++ copy semantics to make it harder to accidentally
65*6777b538SAndroid Build Coastguard Worker // copy large values. Instead, use `Clone()` to manually create a deep copy.
66*6777b538SAndroid Build Coastguard Worker //
67*6777b538SAndroid Build Coastguard Worker // Reading:
68*6777b538SAndroid Build Coastguard Worker //
69*6777b538SAndroid Build Coastguard Worker // `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
70*6777b538SAndroid Build Coastguard Worker // subtype before returning the contained value. `bool`, `int`, `double` are
71*6777b538SAndroid Build Coastguard Worker // returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
72*6777b538SAndroid Build Coastguard Worker // are returned by reference.
73*6777b538SAndroid Build Coastguard Worker //
74*6777b538SAndroid Build Coastguard Worker // `GetIfBool()`, `GetIfInt()`, et cetera return `std::nullopt`/`nullptr` if
75*6777b538SAndroid Build Coastguard Worker // the `Value` does not have the correct subtype; otherwise, returns the value
76*6777b538SAndroid Build Coastguard Worker // wrapped in an `std::optional` (for `bool`, `int`, `double`) or by pointer
77*6777b538SAndroid Build Coastguard Worker // (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
78*6777b538SAndroid Build Coastguard Worker //
79*6777b538SAndroid Build Coastguard Worker // Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
80*6777b538SAndroid Build Coastguard Worker // when the subtype is `Value::Type::INT`. In that case, the stored value is
81*6777b538SAndroid Build Coastguard Worker // coerced to a double before being returned.
82*6777b538SAndroid Build Coastguard Worker //
83*6777b538SAndroid Build Coastguard Worker // Assignment:
84*6777b538SAndroid Build Coastguard Worker //
85*6777b538SAndroid Build Coastguard Worker // It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
86*6777b538SAndroid Build Coastguard Worker // Instead, wrap the underlying type in `Value` before assigning.
87*6777b538SAndroid Build Coastguard Worker //
88*6777b538SAndroid Build Coastguard Worker // ## Dictionaries and Lists
89*6777b538SAndroid Build Coastguard Worker //
90*6777b538SAndroid Build Coastguard Worker // `Value` provides the `Value::Dict` and `Value::List` container types for
91*6777b538SAndroid Build Coastguard Worker // working with dictionaries and lists of values respectively, rather than
92*6777b538SAndroid Build Coastguard Worker // exposing the underlying container types directly. This allows the types to
93*6777b538SAndroid Build Coastguard Worker // provide convenient helpers for dictionaries and lists, as well as giving
94*6777b538SAndroid Build Coastguard Worker // greater flexibility for changing implementation details in the future.
95*6777b538SAndroid Build Coastguard Worker //
96*6777b538SAndroid Build Coastguard Worker // Both container types support enough STL-isms to be usable in range-based for
97*6777b538SAndroid Build Coastguard Worker // loops and generic operations such as those from <algorithm>.
98*6777b538SAndroid Build Coastguard Worker //
99*6777b538SAndroid Build Coastguard Worker // Dictionaries support:
100*6777b538SAndroid Build Coastguard Worker // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
101*6777b538SAndroid Build Coastguard Worker //       `contains()`, `clear()`, `erase()`: Identical to the STL container
102*6777b538SAndroid Build Coastguard Worker //       equivalents, with additional safety checks, e.g. iterators will
103*6777b538SAndroid Build Coastguard Worker //       `CHECK()` if `end()` is dereferenced.
104*6777b538SAndroid Build Coastguard Worker //
105*6777b538SAndroid Build Coastguard Worker // - `Clone()`: Create a deep copy.
106*6777b538SAndroid Build Coastguard Worker // - `Merge()`: Merge another dictionary into this dictionary.
107*6777b538SAndroid Build Coastguard Worker // - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
108*6777b538SAndroid Build Coastguard Worker //       is not present.
109*6777b538SAndroid Build Coastguard Worker // - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
110*6777b538SAndroid Build Coastguard Worker //       `Value` also has the correct subtype. Same return semantics as
111*6777b538SAndroid Build Coastguard Worker //       `GetIfBool()`, `GetIfInt()`, et cetera, returning `std::nullopt` or
112*6777b538SAndroid Build Coastguard Worker //       `nullptr` if the key is not present or the value has the wrong subtype.
113*6777b538SAndroid Build Coastguard Worker // - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
114*6777b538SAndroid Build Coastguard Worker //       of the subtypes that `Value` can hold.
115*6777b538SAndroid Build Coastguard Worker // - `Remove()`: Remove the key from this dictionary, if present.
116*6777b538SAndroid Build Coastguard Worker // - `Extract()`: If the key is present in the dictionary, removes the key from
117*6777b538SAndroid Build Coastguard Worker //       the dictionary and transfers ownership of `Value` to the caller.
118*6777b538SAndroid Build Coastguard Worker //       Otherwise, returns `std::nullopt`.
119*6777b538SAndroid Build Coastguard Worker //
120*6777b538SAndroid Build Coastguard Worker // Dictionaries also support an additional set of helper methods that operate on
121*6777b538SAndroid Build Coastguard Worker // "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
122*6777b538SAndroid Build Coastguard Worker // and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
123*6777b538SAndroid Build Coastguard Worker // intermediate nested dictionaries, separating the components of the path using
124*6777b538SAndroid Build Coastguard Worker // '.' characters. For example, finding a string path on a `Value::Dict` using
125*6777b538SAndroid Build Coastguard Worker // the dotted path:
126*6777b538SAndroid Build Coastguard Worker //
127*6777b538SAndroid Build Coastguard Worker //   "aaa.bbb.ccc"
128*6777b538SAndroid Build Coastguard Worker //
129*6777b538SAndroid Build Coastguard Worker // Will first look for a `Value::Type::DICT` associated with the key "aaa", then
130*6777b538SAndroid Build Coastguard Worker // another `Value::Type::DICT` under the "aaa" dict associated with the
131*6777b538SAndroid Build Coastguard Worker // key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
132*6777b538SAndroid Build Coastguard Worker // with the key "ccc".
133*6777b538SAndroid Build Coastguard Worker //
134*6777b538SAndroid Build Coastguard Worker // If a path only has one component (i.e. has no dots), please use the regular,
135*6777b538SAndroid Build Coastguard Worker // non-path APIs.
136*6777b538SAndroid Build Coastguard Worker //
137*6777b538SAndroid Build Coastguard Worker // Lists support:
138*6777b538SAndroid Build Coastguard Worker // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
139*6777b538SAndroid Build Coastguard Worker //       `rbegin()`, `rend()`, `front()`, `back()`, `reserve()`, `operator[]`,
140*6777b538SAndroid Build Coastguard Worker //       `clear()`, `erase()`: Identical to the STL container equivalents, with
141*6777b538SAndroid Build Coastguard Worker //       additional safety checks, e.g. `operator[]` will `CHECK()` if the index
142*6777b538SAndroid Build Coastguard Worker //       is out of range.
143*6777b538SAndroid Build Coastguard Worker // - `Clone()`: Create a deep copy.
144*6777b538SAndroid Build Coastguard Worker // - `Append()`: Append a value to the end of the list. Accepts `Value` or any
145*6777b538SAndroid Build Coastguard Worker //       of the subtypes that `Value` can hold.
146*6777b538SAndroid Build Coastguard Worker // - `Insert()`: Insert a `Value` at a specified point in the list.
147*6777b538SAndroid Build Coastguard Worker // - `EraseValue()`: Erases all matching `Value`s from the list.
148*6777b538SAndroid Build Coastguard Worker // - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
149*6777b538SAndroid Build Coastguard Worker //       list.
150*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT GSL_OWNER Value {
151*6777b538SAndroid Build Coastguard Worker  public:
152*6777b538SAndroid Build Coastguard Worker   using BlobStorage = std::vector<uint8_t>;
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   class Dict;
155*6777b538SAndroid Build Coastguard Worker   class List;
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker   enum class Type : unsigned char {
158*6777b538SAndroid Build Coastguard Worker     NONE = 0,
159*6777b538SAndroid Build Coastguard Worker     BOOLEAN,
160*6777b538SAndroid Build Coastguard Worker     INTEGER,
161*6777b538SAndroid Build Coastguard Worker     DOUBLE,
162*6777b538SAndroid Build Coastguard Worker     STRING,
163*6777b538SAndroid Build Coastguard Worker     BINARY,
164*6777b538SAndroid Build Coastguard Worker     DICT,
165*6777b538SAndroid Build Coastguard Worker     LIST,
166*6777b538SAndroid Build Coastguard Worker     // Note: Do not add more types. See the file-level comment above for why.
167*6777b538SAndroid Build Coastguard Worker   };
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker   // Adaptors for converting from the old way to the new way and vice versa.
170*6777b538SAndroid Build Coastguard Worker   static Value FromUniquePtrValue(std::unique_ptr<Value> val);
171*6777b538SAndroid Build Coastguard Worker   static std::unique_ptr<Value> ToUniquePtrValue(Value val);
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   Value() noexcept;
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   Value(Value&&) noexcept;
176*6777b538SAndroid Build Coastguard Worker   Value& operator=(Value&&) noexcept;
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   // Deleted to prevent accidental copying.
179*6777b538SAndroid Build Coastguard Worker   Value(const Value&) = delete;
180*6777b538SAndroid Build Coastguard Worker   Value& operator=(const Value&) = delete;
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   // Creates a deep copy of this value.
183*6777b538SAndroid Build Coastguard Worker   Value Clone() const;
184*6777b538SAndroid Build Coastguard Worker 
185*6777b538SAndroid Build Coastguard Worker   // Creates a `Value` of `type`. The data of the corresponding type will be
186*6777b538SAndroid Build Coastguard Worker   // default constructed.
187*6777b538SAndroid Build Coastguard Worker   explicit Value(Type type);
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker   // Constructor for `Value::Type::BOOLEAN`.
190*6777b538SAndroid Build Coastguard Worker   explicit Value(bool value);
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // Prevent pointers from implicitly converting to bool. Another way to write
193*6777b538SAndroid Build Coastguard Worker   // this would be to template the bool constructor and use SFINAE to only allow
194*6777b538SAndroid Build Coastguard Worker   // use if `std::is_same_v<T, bool>` is true, but this has surprising behavior
195*6777b538SAndroid Build Coastguard Worker   // with range-based for loops over a `std::vector<bool>` (which will
196*6777b538SAndroid Build Coastguard Worker   // unintuitively match the int overload instead).
197*6777b538SAndroid Build Coastguard Worker   //
198*6777b538SAndroid Build Coastguard Worker   // The `const` is load-bearing; otherwise, a `char*` argument would prefer the
199*6777b538SAndroid Build Coastguard Worker   // deleted overload due to requiring a qualification conversion.
200*6777b538SAndroid Build Coastguard Worker   template <typename T>
201*6777b538SAndroid Build Coastguard Worker   explicit Value(const T*) = delete;
202*6777b538SAndroid Build Coastguard Worker 
203*6777b538SAndroid Build Coastguard Worker   // Constructor for `Value::Type::INT`.
204*6777b538SAndroid Build Coastguard Worker   explicit Value(int value);
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker   // Constructor for `Value::Type::DOUBLE`.
207*6777b538SAndroid Build Coastguard Worker   explicit Value(double value);
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker   // Constructors for `Value::Type::STRING`.
210*6777b538SAndroid Build Coastguard Worker   explicit Value(StringPiece value);
211*6777b538SAndroid Build Coastguard Worker   explicit Value(StringPiece16 value);
212*6777b538SAndroid Build Coastguard Worker   // `char*` and `char16_t*` are needed to provide a more specific overload than
213*6777b538SAndroid Build Coastguard Worker   // the deleted `const T*` overload above.
214*6777b538SAndroid Build Coastguard Worker   explicit Value(const char* value);
215*6777b538SAndroid Build Coastguard Worker   explicit Value(const char16_t* value);
216*6777b538SAndroid Build Coastguard Worker   // `std::string&&` allows for efficient move construction.
217*6777b538SAndroid Build Coastguard Worker   explicit Value(std::string&& value) noexcept;
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker   // Constructors for `Value::Type::BINARY`.
220*6777b538SAndroid Build Coastguard Worker   explicit Value(const std::vector<char>& value);
221*6777b538SAndroid Build Coastguard Worker   explicit Value(base::span<const uint8_t> value);
222*6777b538SAndroid Build Coastguard Worker   explicit Value(BlobStorage&& value) noexcept;
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker   // Constructor for `Value::Type::DICT`.
225*6777b538SAndroid Build Coastguard Worker   explicit Value(Dict&& value) noexcept;
226*6777b538SAndroid Build Coastguard Worker 
227*6777b538SAndroid Build Coastguard Worker   // Constructor for `Value::Type::LIST`.
228*6777b538SAndroid Build Coastguard Worker   explicit Value(List&& value) noexcept;
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker   ~Value();
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   // Returns the name for a given `type`.
233*6777b538SAndroid Build Coastguard Worker   static const char* GetTypeName(Type type);
234*6777b538SAndroid Build Coastguard Worker 
235*6777b538SAndroid Build Coastguard Worker   // Returns the type of the value stored by the current Value object.
type()236*6777b538SAndroid Build Coastguard Worker   Type type() const { return static_cast<Type>(data_.index()); }
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   // Returns true if the current object represents a given type.
is_none()239*6777b538SAndroid Build Coastguard Worker   bool is_none() const { return type() == Type::NONE; }
is_bool()240*6777b538SAndroid Build Coastguard Worker   bool is_bool() const { return type() == Type::BOOLEAN; }
is_int()241*6777b538SAndroid Build Coastguard Worker   bool is_int() const { return type() == Type::INTEGER; }
is_double()242*6777b538SAndroid Build Coastguard Worker   bool is_double() const { return type() == Type::DOUBLE; }
is_string()243*6777b538SAndroid Build Coastguard Worker   bool is_string() const { return type() == Type::STRING; }
is_blob()244*6777b538SAndroid Build Coastguard Worker   bool is_blob() const { return type() == Type::BINARY; }
is_dict()245*6777b538SAndroid Build Coastguard Worker   bool is_dict() const { return type() == Type::DICT; }
is_list()246*6777b538SAndroid Build Coastguard Worker   bool is_list() const { return type() == Type::LIST; }
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   // Returns the stored data if the type matches, or `std::nullopt`/`nullptr`
249*6777b538SAndroid Build Coastguard Worker   // otherwise. `bool`, `int`, and `double` are returned in a wrapped
250*6777b538SAndroid Build Coastguard Worker   // `std::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
251*6777b538SAndroid Build Coastguard Worker   // pointer.
252*6777b538SAndroid Build Coastguard Worker   std::optional<bool> GetIfBool() const;
253*6777b538SAndroid Build Coastguard Worker   std::optional<int> GetIfInt() const;
254*6777b538SAndroid Build Coastguard Worker   // Returns a non-null value for both `Value::Type::DOUBLE` and
255*6777b538SAndroid Build Coastguard Worker   // `Value::Type::INT`, converting the latter to a double.
256*6777b538SAndroid Build Coastguard Worker   std::optional<double> GetIfDouble() const;
257*6777b538SAndroid Build Coastguard Worker   const std::string* GetIfString() const;
258*6777b538SAndroid Build Coastguard Worker   std::string* GetIfString();
259*6777b538SAndroid Build Coastguard Worker   const BlobStorage* GetIfBlob() const;
260*6777b538SAndroid Build Coastguard Worker   const Dict* GetIfDict() const;
261*6777b538SAndroid Build Coastguard Worker   Dict* GetIfDict();
262*6777b538SAndroid Build Coastguard Worker   const List* GetIfList() const;
263*6777b538SAndroid Build Coastguard Worker   List* GetIfList();
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker   // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
266*6777b538SAndroid Build Coastguard Worker   // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
267*6777b538SAndroid Build Coastguard Worker   // `Value::Dict`, and `Value::List` are returned by reference.
268*6777b538SAndroid Build Coastguard Worker   bool GetBool() const;
269*6777b538SAndroid Build Coastguard Worker   int GetInt() const;
270*6777b538SAndroid Build Coastguard Worker   // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
271*6777b538SAndroid Build Coastguard Worker   // converting the latter to a double.
272*6777b538SAndroid Build Coastguard Worker   double GetDouble() const;
273*6777b538SAndroid Build Coastguard Worker   const std::string& GetString() const;
274*6777b538SAndroid Build Coastguard Worker   std::string& GetString();
275*6777b538SAndroid Build Coastguard Worker   const BlobStorage& GetBlob() const;
276*6777b538SAndroid Build Coastguard Worker   const Dict& GetDict() const;
277*6777b538SAndroid Build Coastguard Worker   Dict& GetDict();
278*6777b538SAndroid Build Coastguard Worker   const List& GetList() const;
279*6777b538SAndroid Build Coastguard Worker   List& GetList();
280*6777b538SAndroid Build Coastguard Worker 
281*6777b538SAndroid Build Coastguard Worker   // Transfers ownership of the underlying value. Similarly to `Get...()`
282*6777b538SAndroid Build Coastguard Worker   // variants above, fails with a `CHECK()` on a type mismatch. After
283*6777b538SAndroid Build Coastguard Worker   // transferring the ownership `*this` is in a valid, but unspecified, state.
284*6777b538SAndroid Build Coastguard Worker   // Prefer over `std::move(value.Get...())` so clang-tidy can warn about
285*6777b538SAndroid Build Coastguard Worker   // potential use-after-move mistakes.
286*6777b538SAndroid Build Coastguard Worker   std::string TakeString() &&;
287*6777b538SAndroid Build Coastguard Worker   Dict TakeDict() &&;
288*6777b538SAndroid Build Coastguard Worker   List TakeList() &&;
289*6777b538SAndroid Build Coastguard Worker 
290*6777b538SAndroid Build Coastguard Worker   // Represents a dictionary of string keys to Values.
291*6777b538SAndroid Build Coastguard Worker   class BASE_EXPORT GSL_OWNER Dict {
292*6777b538SAndroid Build Coastguard Worker    public:
293*6777b538SAndroid Build Coastguard Worker     using iterator = detail::dict_iterator;
294*6777b538SAndroid Build Coastguard Worker     using const_iterator = detail::const_dict_iterator;
295*6777b538SAndroid Build Coastguard Worker 
296*6777b538SAndroid Build Coastguard Worker     Dict();
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker     Dict(Dict&&) noexcept;
299*6777b538SAndroid Build Coastguard Worker     Dict& operator=(Dict&&) noexcept;
300*6777b538SAndroid Build Coastguard Worker 
301*6777b538SAndroid Build Coastguard Worker     // Deleted to prevent accidental copying.
302*6777b538SAndroid Build Coastguard Worker     Dict(const Dict&) = delete;
303*6777b538SAndroid Build Coastguard Worker     Dict& operator=(const Dict&) = delete;
304*6777b538SAndroid Build Coastguard Worker 
305*6777b538SAndroid Build Coastguard Worker     // Takes move_iterators iterators that return std::pair<std::string, Value>,
306*6777b538SAndroid Build Coastguard Worker     // and moves their values into a new Dict. Adding all entries at once
307*6777b538SAndroid Build Coastguard Worker     // results in a faster initial sort operation. Takes move iterators to avoid
308*6777b538SAndroid Build Coastguard Worker     // having to clone the input.
309*6777b538SAndroid Build Coastguard Worker     template <class IteratorType>
Dict(std::move_iterator<IteratorType> first,std::move_iterator<IteratorType> last)310*6777b538SAndroid Build Coastguard Worker     explicit Dict(std::move_iterator<IteratorType> first,
311*6777b538SAndroid Build Coastguard Worker                   std::move_iterator<IteratorType> last) {
312*6777b538SAndroid Build Coastguard Worker       // Need to move into a vector first, since `storage_` currently uses
313*6777b538SAndroid Build Coastguard Worker       // unique_ptrs.
314*6777b538SAndroid Build Coastguard Worker       std::vector<std::pair<std::string, std::unique_ptr<Value>>> values;
315*6777b538SAndroid Build Coastguard Worker       for (auto current = first; current != last; ++current) {
316*6777b538SAndroid Build Coastguard Worker         // With move iterators, no need to call Clone(), but do need to move
317*6777b538SAndroid Build Coastguard Worker         // to a temporary first, as accessing either field individually will
318*6777b538SAndroid Build Coastguard Worker         // directly from the iterator will delete the other field.
319*6777b538SAndroid Build Coastguard Worker         auto value = *current;
320*6777b538SAndroid Build Coastguard Worker         values.emplace_back(std::move(value.first),
321*6777b538SAndroid Build Coastguard Worker                             std::make_unique<Value>(std::move(value.second)));
322*6777b538SAndroid Build Coastguard Worker       }
323*6777b538SAndroid Build Coastguard Worker       storage_ =
324*6777b538SAndroid Build Coastguard Worker           flat_map<std::string, std::unique_ptr<Value>>(std::move(values));
325*6777b538SAndroid Build Coastguard Worker     }
326*6777b538SAndroid Build Coastguard Worker 
327*6777b538SAndroid Build Coastguard Worker     ~Dict();
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker     // Returns true if there are no entries in this dictionary and false
330*6777b538SAndroid Build Coastguard Worker     // otherwise.
331*6777b538SAndroid Build Coastguard Worker     bool empty() const;
332*6777b538SAndroid Build Coastguard Worker 
333*6777b538SAndroid Build Coastguard Worker     // Returns the number of entries in this dictionary.
334*6777b538SAndroid Build Coastguard Worker     size_t size() const;
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker     // Returns an iterator to the first entry in this dictionary.
337*6777b538SAndroid Build Coastguard Worker     iterator begin();
338*6777b538SAndroid Build Coastguard Worker     const_iterator begin() const;
339*6777b538SAndroid Build Coastguard Worker     const_iterator cbegin() const;
340*6777b538SAndroid Build Coastguard Worker 
341*6777b538SAndroid Build Coastguard Worker     // Returns an iterator following the last entry in this dictionary. May not
342*6777b538SAndroid Build Coastguard Worker     // be dereferenced.
343*6777b538SAndroid Build Coastguard Worker     iterator end();
344*6777b538SAndroid Build Coastguard Worker     const_iterator end() const;
345*6777b538SAndroid Build Coastguard Worker     const_iterator cend() const;
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker     // Returns true if `key` is an entry in this dictionary.
348*6777b538SAndroid Build Coastguard Worker     bool contains(base::StringPiece key) const;
349*6777b538SAndroid Build Coastguard Worker 
350*6777b538SAndroid Build Coastguard Worker     // Removes all entries from this dictionary.
351*6777b538SAndroid Build Coastguard Worker     REINITIALIZES_AFTER_MOVE void clear();
352*6777b538SAndroid Build Coastguard Worker 
353*6777b538SAndroid Build Coastguard Worker     // Removes the entry referenced by `pos` in this dictionary and returns an
354*6777b538SAndroid Build Coastguard Worker     // iterator to the entry following the removed entry.
355*6777b538SAndroid Build Coastguard Worker     iterator erase(iterator pos);
356*6777b538SAndroid Build Coastguard Worker     iterator erase(const_iterator pos);
357*6777b538SAndroid Build Coastguard Worker 
358*6777b538SAndroid Build Coastguard Worker     // Creates a deep copy of this dictionary.
359*6777b538SAndroid Build Coastguard Worker     Dict Clone() const;
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker     // Merges the entries from `dict` into this dictionary. If an entry with the
362*6777b538SAndroid Build Coastguard Worker     // same key exists in this dictionary and `dict`:
363*6777b538SAndroid Build Coastguard Worker     // - if both entries are dictionaries, they will be recursively merged
364*6777b538SAndroid Build Coastguard Worker     // - otherwise, the already-existing entry in this dictionary will be
365*6777b538SAndroid Build Coastguard Worker     //   overwritten with the entry from `dict`.
366*6777b538SAndroid Build Coastguard Worker     void Merge(Dict dict);
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker     // Finds the entry corresponding to `key` in this dictionary. Returns
369*6777b538SAndroid Build Coastguard Worker     // nullptr if there is no such entry.
370*6777b538SAndroid Build Coastguard Worker     const Value* Find(StringPiece key) const;
371*6777b538SAndroid Build Coastguard Worker     Value* Find(StringPiece key);
372*6777b538SAndroid Build Coastguard Worker 
373*6777b538SAndroid Build Coastguard Worker     // Similar to `Find()` above, but returns `std::nullopt`/`nullptr` if the
374*6777b538SAndroid Build Coastguard Worker     // type of the entry does not match. `bool`, `int`, and `double` are
375*6777b538SAndroid Build Coastguard Worker     // returned in a wrapped `std::optional`; blobs, `Value::Dict`, and
376*6777b538SAndroid Build Coastguard Worker     // `Value::List` are returned by pointer.
377*6777b538SAndroid Build Coastguard Worker     std::optional<bool> FindBool(StringPiece key) const;
378*6777b538SAndroid Build Coastguard Worker     std::optional<int> FindInt(StringPiece key) const;
379*6777b538SAndroid Build Coastguard Worker     // Returns a non-null value for both `Value::Type::DOUBLE` and
380*6777b538SAndroid Build Coastguard Worker     // `Value::Type::INT`, converting the latter to a double.
381*6777b538SAndroid Build Coastguard Worker     std::optional<double> FindDouble(StringPiece key) const;
382*6777b538SAndroid Build Coastguard Worker     const std::string* FindString(StringPiece key) const;
383*6777b538SAndroid Build Coastguard Worker     std::string* FindString(StringPiece key);
384*6777b538SAndroid Build Coastguard Worker     const BlobStorage* FindBlob(StringPiece key) const;
385*6777b538SAndroid Build Coastguard Worker     const Dict* FindDict(StringPiece key) const;
386*6777b538SAndroid Build Coastguard Worker     Dict* FindDict(StringPiece key);
387*6777b538SAndroid Build Coastguard Worker     const List* FindList(StringPiece key) const;
388*6777b538SAndroid Build Coastguard Worker     List* FindList(StringPiece key);
389*6777b538SAndroid Build Coastguard Worker 
390*6777b538SAndroid Build Coastguard Worker     // If there's a value of the specified type at `key` in this dictionary,
391*6777b538SAndroid Build Coastguard Worker     // returns it. Otherwise, creates an empty container of the specified type,
392*6777b538SAndroid Build Coastguard Worker     // inserts it at `key`, and returns it. If there's a value of some other
393*6777b538SAndroid Build Coastguard Worker     // type at `key`, will overwrite that entry.
394*6777b538SAndroid Build Coastguard Worker     Dict* EnsureDict(StringPiece key);
395*6777b538SAndroid Build Coastguard Worker     List* EnsureList(StringPiece key);
396*6777b538SAndroid Build Coastguard Worker 
397*6777b538SAndroid Build Coastguard Worker     // Sets an entry with `key` and `value` in this dictionary, overwriting any
398*6777b538SAndroid Build Coastguard Worker     // existing entry with the same `key`. Returns a pointer to the set `value`.
399*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, Value&& value) &;
400*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, bool value) &;
401*6777b538SAndroid Build Coastguard Worker     template <typename T>
402*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece, const T*) & = delete;
403*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, int value) &;
404*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, double value) &;
405*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, StringPiece value) &;
406*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, StringPiece16 value) &;
407*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, const char* value) &;
408*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, const char16_t* value) &;
409*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, std::string&& value) &;
410*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, BlobStorage&& value) &;
411*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, Dict&& value) &;
412*6777b538SAndroid Build Coastguard Worker     Value* Set(StringPiece key, List&& value) &;
413*6777b538SAndroid Build Coastguard Worker 
414*6777b538SAndroid Build Coastguard Worker     // Rvalue overrides of the `Set` methods, which allow you to construct
415*6777b538SAndroid Build Coastguard Worker     // a `Value::Dict` builder-style:
416*6777b538SAndroid Build Coastguard Worker     //
417*6777b538SAndroid Build Coastguard Worker     // Value::Dict result =
418*6777b538SAndroid Build Coastguard Worker     //     Value::Dict()
419*6777b538SAndroid Build Coastguard Worker     //         .Set("key-1", "first value")
420*6777b538SAndroid Build Coastguard Worker     //         .Set("key-2", 2)
421*6777b538SAndroid Build Coastguard Worker     //         .Set("key-3", true)
422*6777b538SAndroid Build Coastguard Worker     //         .Set("nested-dictionary", Value::Dict()
423*6777b538SAndroid Build Coastguard Worker     //                                       .Set("nested-key-1", "value")
424*6777b538SAndroid Build Coastguard Worker     //                                       .Set("nested-key-2", true))
425*6777b538SAndroid Build Coastguard Worker     //         .Set("nested-list", Value::List()
426*6777b538SAndroid Build Coastguard Worker     //                                 .Append("nested-list-value")
427*6777b538SAndroid Build Coastguard Worker     //                                 .Append(5)
428*6777b538SAndroid Build Coastguard Worker     //                                 .Append(true));
429*6777b538SAndroid Build Coastguard Worker     //
430*6777b538SAndroid Build Coastguard Worker     // Each method returns a rvalue reference to `this`, so this is as efficient
431*6777b538SAndroid Build Coastguard Worker     // as stand-alone calls to `Set`, while also making it harder to
432*6777b538SAndroid Build Coastguard Worker     // accidentally insert items in the wrong dictionary.
433*6777b538SAndroid Build Coastguard Worker     //
434*6777b538SAndroid Build Coastguard Worker     // The equivalent code without using these builder-style methods:
435*6777b538SAndroid Build Coastguard Worker     //
436*6777b538SAndroid Build Coastguard Worker     // Value::Dict no_builder_example;
437*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Set("key-1", "first value")
438*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Set("key-2", 2)
439*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Set("key-3", true)
440*6777b538SAndroid Build Coastguard Worker     // Value::Dict nested_dictionary;
441*6777b538SAndroid Build Coastguard Worker     // nested_dictionary.Set("nested-key-1", "value");
442*6777b538SAndroid Build Coastguard Worker     // nested_dictionary.Set("nested-key-2", true);
443*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Set("nested_dictionary",
444*6777b538SAndroid Build Coastguard Worker     //                        std::move(nested_dictionary));
445*6777b538SAndroid Build Coastguard Worker     // Value::List nested_list;
446*6777b538SAndroid Build Coastguard Worker     // nested_list.Append("nested-list-value");
447*6777b538SAndroid Build Coastguard Worker     // nested_list.Append(5);
448*6777b538SAndroid Build Coastguard Worker     // nested_list.Append(true);
449*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Set("nested-list", std::move(nested_list));
450*6777b538SAndroid Build Coastguard Worker     //
451*6777b538SAndroid Build Coastguard Worker     // Sometimes `git cl format` does a less than perfect job formatting these
452*6777b538SAndroid Build Coastguard Worker     // chained `Set` calls. In these cases you can use a trailing empty comment
453*6777b538SAndroid Build Coastguard Worker     // to influence the code formatting:
454*6777b538SAndroid Build Coastguard Worker     //
455*6777b538SAndroid Build Coastguard Worker     // Value::Dict result = Value::Dict().Set(
456*6777b538SAndroid Build Coastguard Worker     //     "nested",
457*6777b538SAndroid Build Coastguard Worker     //     base::Value::Dict().Set("key", "value").Set("other key", "other"));
458*6777b538SAndroid Build Coastguard Worker     //
459*6777b538SAndroid Build Coastguard Worker     // Value::Dict result = Value::Dict().Set("nested",
460*6777b538SAndroid Build Coastguard Worker     //                                        base::Value::Dict() //
461*6777b538SAndroid Build Coastguard Worker     //                                           .Set("key", "value")
462*6777b538SAndroid Build Coastguard Worker     //                                           .Set("other key", "value"));
463*6777b538SAndroid Build Coastguard Worker     //
464*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, Value&& value) &&;
465*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, bool value) &&;
466*6777b538SAndroid Build Coastguard Worker     template <typename T>
467*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece, const T*) && = delete;
468*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, int value) &&;
469*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, double value) &&;
470*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, StringPiece value) &&;
471*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, StringPiece16 value) &&;
472*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, const char* value) &&;
473*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, const char16_t* value) &&;
474*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, std::string&& value) &&;
475*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, BlobStorage&& value) &&;
476*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, Dict&& value) &&;
477*6777b538SAndroid Build Coastguard Worker     Dict&& Set(StringPiece key, List&& value) &&;
478*6777b538SAndroid Build Coastguard Worker 
479*6777b538SAndroid Build Coastguard Worker     // Removes the entry corresponding to `key` from this dictionary. Returns
480*6777b538SAndroid Build Coastguard Worker     // true if an entry was removed or false otherwise.
481*6777b538SAndroid Build Coastguard Worker     bool Remove(StringPiece key);
482*6777b538SAndroid Build Coastguard Worker 
483*6777b538SAndroid Build Coastguard Worker     // Similar to `Remove()`, but returns the value corresponding to the removed
484*6777b538SAndroid Build Coastguard Worker     // entry or `std::nullopt` otherwise.
485*6777b538SAndroid Build Coastguard Worker     std::optional<Value> Extract(StringPiece key);
486*6777b538SAndroid Build Coastguard Worker 
487*6777b538SAndroid Build Coastguard Worker     // Equivalent to the above methods but operating on paths instead of keys.
488*6777b538SAndroid Build Coastguard Worker     // A path is shorthand syntax for referring to a key nested inside
489*6777b538SAndroid Build Coastguard Worker     // intermediate dictionaries, with components delimited by ".". Paths may
490*6777b538SAndroid Build Coastguard Worker     // not be empty.
491*6777b538SAndroid Build Coastguard Worker     //
492*6777b538SAndroid Build Coastguard Worker     // Prefer the non-path methods above when possible. Paths that have only one
493*6777b538SAndroid Build Coastguard Worker     // component (i.e. no dots in the path) should never use the path-based
494*6777b538SAndroid Build Coastguard Worker     // methods.
495*6777b538SAndroid Build Coastguard Worker     //
496*6777b538SAndroid Build Coastguard Worker     // Originally, the path-based APIs were the only way of specifying a key, so
497*6777b538SAndroid Build Coastguard Worker     // there are likely to be many legacy (and unnecessary) uses of the path
498*6777b538SAndroid Build Coastguard Worker     // APIs that do not actually require traversing nested dictionaries.
499*6777b538SAndroid Build Coastguard Worker     const Value* FindByDottedPath(StringPiece path) const;
500*6777b538SAndroid Build Coastguard Worker     Value* FindByDottedPath(StringPiece path);
501*6777b538SAndroid Build Coastguard Worker 
502*6777b538SAndroid Build Coastguard Worker     std::optional<bool> FindBoolByDottedPath(StringPiece path) const;
503*6777b538SAndroid Build Coastguard Worker     std::optional<int> FindIntByDottedPath(StringPiece path) const;
504*6777b538SAndroid Build Coastguard Worker     // Returns a non-null value for both `Value::Type::DOUBLE` and
505*6777b538SAndroid Build Coastguard Worker     // `Value::Type::INT`, converting the latter to a double.
506*6777b538SAndroid Build Coastguard Worker     std::optional<double> FindDoubleByDottedPath(StringPiece path) const;
507*6777b538SAndroid Build Coastguard Worker     const std::string* FindStringByDottedPath(StringPiece path) const;
508*6777b538SAndroid Build Coastguard Worker     std::string* FindStringByDottedPath(StringPiece path);
509*6777b538SAndroid Build Coastguard Worker     const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
510*6777b538SAndroid Build Coastguard Worker     const Dict* FindDictByDottedPath(StringPiece path) const;
511*6777b538SAndroid Build Coastguard Worker     Dict* FindDictByDottedPath(StringPiece path);
512*6777b538SAndroid Build Coastguard Worker     const List* FindListByDottedPath(StringPiece path) const;
513*6777b538SAndroid Build Coastguard Worker     List* FindListByDottedPath(StringPiece path);
514*6777b538SAndroid Build Coastguard Worker 
515*6777b538SAndroid Build Coastguard Worker     // Creates a new entry with a dictionary for any non-last component that is
516*6777b538SAndroid Build Coastguard Worker     // missing an entry while performing the path traversal. Will fail if any
517*6777b538SAndroid Build Coastguard Worker     // non-last component of the path refers to an already-existing entry that
518*6777b538SAndroid Build Coastguard Worker     // is not a dictionary. Returns `nullptr` on failure.
519*6777b538SAndroid Build Coastguard Worker     //
520*6777b538SAndroid Build Coastguard Worker     // Warning: repeatedly using this API to enter entries in the same nested
521*6777b538SAndroid Build Coastguard Worker     // dictionary is inefficient, so please do not write the following:
522*6777b538SAndroid Build Coastguard Worker     //
523*6777b538SAndroid Build Coastguard Worker     // bad_example.SetByDottedPath("a.nested.dictionary.field_1", 1);
524*6777b538SAndroid Build Coastguard Worker     // bad_example.SetByDottedPath("a.nested.dictionary.field_2", "value");
525*6777b538SAndroid Build Coastguard Worker     // bad_example.SetByDottedPath("a.nested.dictionary.field_3", 1);
526*6777b538SAndroid Build Coastguard Worker     //
527*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, Value&& value) &;
528*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, bool value) &;
529*6777b538SAndroid Build Coastguard Worker     template <typename T>
530*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece, const T*) & = delete;
531*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, int value) &;
532*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, double value) &;
533*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, StringPiece value) &;
534*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, StringPiece16 value) &;
535*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, const char* value) &;
536*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, const char16_t* value) &;
537*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, std::string&& value) &;
538*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, BlobStorage&& value) &;
539*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, Dict&& value) &;
540*6777b538SAndroid Build Coastguard Worker     Value* SetByDottedPath(StringPiece path, List&& value) &;
541*6777b538SAndroid Build Coastguard Worker 
542*6777b538SAndroid Build Coastguard Worker     // Rvalue overrides of the `SetByDottedPath` methods, which allow you to
543*6777b538SAndroid Build Coastguard Worker     // construct a `Value::Dict` builder-style:
544*6777b538SAndroid Build Coastguard Worker     //
545*6777b538SAndroid Build Coastguard Worker     // Value::Dict result =
546*6777b538SAndroid Build Coastguard Worker     //     Value::Dict()
547*6777b538SAndroid Build Coastguard Worker     //         .SetByDottedPath("a.nested.dictionary.with.key-1", "first value")
548*6777b538SAndroid Build Coastguard Worker     //         .Set("local-key-1", 2));
549*6777b538SAndroid Build Coastguard Worker     //
550*6777b538SAndroid Build Coastguard Worker     // Each method returns a rvalue reference to `this`, so this is as efficient
551*6777b538SAndroid Build Coastguard Worker     // as (and less mistake-prone than) stand-alone calls to `Set`.
552*6777b538SAndroid Build Coastguard Worker     //
553*6777b538SAndroid Build Coastguard Worker     // Warning: repeatedly using this API to enter entries in the same nested
554*6777b538SAndroid Build Coastguard Worker     // dictionary is inefficient, so do not write this:
555*6777b538SAndroid Build Coastguard Worker     //
556*6777b538SAndroid Build Coastguard Worker     // Value::Dict bad_example =
557*6777b538SAndroid Build Coastguard Worker     //   Value::Dict()
558*6777b538SAndroid Build Coastguard Worker     //     .SetByDottedPath("nested.dictionary.key-1", "first value")
559*6777b538SAndroid Build Coastguard Worker     //     .SetByDottedPath("nested.dictionary.key-2", "second value")
560*6777b538SAndroid Build Coastguard Worker     //     .SetByDottedPath("nested.dictionary.key-3", "third value");
561*6777b538SAndroid Build Coastguard Worker     //
562*6777b538SAndroid Build Coastguard Worker     // Instead, simply write this
563*6777b538SAndroid Build Coastguard Worker     //
564*6777b538SAndroid Build Coastguard Worker     // Value::Dict good_example =
565*6777b538SAndroid Build Coastguard Worker     //   Value::Dict()
566*6777b538SAndroid Build Coastguard Worker     //     .Set("nested",
567*6777b538SAndroid Build Coastguard Worker     //          base::Value::Dict()
568*6777b538SAndroid Build Coastguard Worker     //            .Set("dictionary",
569*6777b538SAndroid Build Coastguard Worker     //                 base::Value::Dict()
570*6777b538SAndroid Build Coastguard Worker     //                   .Set(key-1", "first value")
571*6777b538SAndroid Build Coastguard Worker     //                   .Set(key-2", "second value")
572*6777b538SAndroid Build Coastguard Worker     //                   .Set(key-3", "third value")));
573*6777b538SAndroid Build Coastguard Worker     //
574*6777b538SAndroid Build Coastguard Worker     //
575*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, Value&& value) &&;
576*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, bool value) &&;
577*6777b538SAndroid Build Coastguard Worker     template <typename T>
578*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece, const T*) && = delete;
579*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, int value) &&;
580*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, double value) &&;
581*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, StringPiece value) &&;
582*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, StringPiece16 value) &&;
583*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, const char* value) &&;
584*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, const char16_t* value) &&;
585*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, std::string&& value) &&;
586*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, BlobStorage&& value) &&;
587*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, Dict&& value) &&;
588*6777b538SAndroid Build Coastguard Worker     Dict&& SetByDottedPath(StringPiece path, List&& value) &&;
589*6777b538SAndroid Build Coastguard Worker 
590*6777b538SAndroid Build Coastguard Worker     bool RemoveByDottedPath(StringPiece path);
591*6777b538SAndroid Build Coastguard Worker 
592*6777b538SAndroid Build Coastguard Worker     std::optional<Value> ExtractByDottedPath(StringPiece path);
593*6777b538SAndroid Build Coastguard Worker 
594*6777b538SAndroid Build Coastguard Worker     // Estimates dynamic memory usage. Requires tracing support
595*6777b538SAndroid Build Coastguard Worker     // (enable_base_tracing gn flag), otherwise always returns 0. See
596*6777b538SAndroid Build Coastguard Worker     // base/trace_event/memory_usage_estimator.h for more info.
597*6777b538SAndroid Build Coastguard Worker     size_t EstimateMemoryUsage() const;
598*6777b538SAndroid Build Coastguard Worker 
599*6777b538SAndroid Build Coastguard Worker     // Serializes to a string for logging and debug purposes.
600*6777b538SAndroid Build Coastguard Worker     std::string DebugString() const;
601*6777b538SAndroid Build Coastguard Worker 
602*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
603*6777b538SAndroid Build Coastguard Worker     // Write this object into a trace.
604*6777b538SAndroid Build Coastguard Worker     void WriteIntoTrace(perfetto::TracedValue) const;
605*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
606*6777b538SAndroid Build Coastguard Worker 
607*6777b538SAndroid Build Coastguard Worker    private:
608*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs);
609*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs);
610*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs);
611*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
612*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
613*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);
614*6777b538SAndroid Build Coastguard Worker 
615*6777b538SAndroid Build Coastguard Worker     explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);
616*6777b538SAndroid Build Coastguard Worker 
617*6777b538SAndroid Build Coastguard Worker     // TODO(dcheng): Replace with `flat_map<std::string, Value>` once no caller
618*6777b538SAndroid Build Coastguard Worker     // relies on stability of pointers anymore.
619*6777b538SAndroid Build Coastguard Worker     flat_map<std::string, std::unique_ptr<Value>> storage_;
620*6777b538SAndroid Build Coastguard Worker   };
621*6777b538SAndroid Build Coastguard Worker 
622*6777b538SAndroid Build Coastguard Worker   // Represents a list of Values.
623*6777b538SAndroid Build Coastguard Worker   class BASE_EXPORT GSL_OWNER List {
624*6777b538SAndroid Build Coastguard Worker    public:
625*6777b538SAndroid Build Coastguard Worker     using iterator = CheckedContiguousIterator<Value>;
626*6777b538SAndroid Build Coastguard Worker     using const_iterator = CheckedContiguousConstIterator<Value>;
627*6777b538SAndroid Build Coastguard Worker     using reverse_iterator = std::reverse_iterator<iterator>;
628*6777b538SAndroid Build Coastguard Worker     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
629*6777b538SAndroid Build Coastguard Worker     using value_type = Value;
630*6777b538SAndroid Build Coastguard Worker 
631*6777b538SAndroid Build Coastguard Worker     // Creates a list with the given capacity reserved.
632*6777b538SAndroid Build Coastguard Worker     // Correctly using this will greatly reduce the code size and improve
633*6777b538SAndroid Build Coastguard Worker     // performance when creating a list whose size is known up front.
634*6777b538SAndroid Build Coastguard Worker     static List with_capacity(size_t capacity);
635*6777b538SAndroid Build Coastguard Worker 
636*6777b538SAndroid Build Coastguard Worker     List();
637*6777b538SAndroid Build Coastguard Worker 
638*6777b538SAndroid Build Coastguard Worker     List(List&&) noexcept;
639*6777b538SAndroid Build Coastguard Worker     List& operator=(List&&) noexcept;
640*6777b538SAndroid Build Coastguard Worker 
641*6777b538SAndroid Build Coastguard Worker     // Deleted to prevent accidental copying.
642*6777b538SAndroid Build Coastguard Worker     List(const List&) = delete;
643*6777b538SAndroid Build Coastguard Worker     List& operator=(const List&) = delete;
644*6777b538SAndroid Build Coastguard Worker 
645*6777b538SAndroid Build Coastguard Worker     ~List();
646*6777b538SAndroid Build Coastguard Worker 
647*6777b538SAndroid Build Coastguard Worker     // Returns true if there are no values in this list and false otherwise.
648*6777b538SAndroid Build Coastguard Worker     bool empty() const;
649*6777b538SAndroid Build Coastguard Worker 
650*6777b538SAndroid Build Coastguard Worker     // Returns the number of values in this list.
651*6777b538SAndroid Build Coastguard Worker     size_t size() const;
652*6777b538SAndroid Build Coastguard Worker 
653*6777b538SAndroid Build Coastguard Worker     // Returns an iterator to the first value in this list.
654*6777b538SAndroid Build Coastguard Worker     iterator begin();
655*6777b538SAndroid Build Coastguard Worker     const_iterator begin() const;
656*6777b538SAndroid Build Coastguard Worker     const_iterator cbegin() const;
657*6777b538SAndroid Build Coastguard Worker 
658*6777b538SAndroid Build Coastguard Worker     // Returns an iterator following the last value in this list. May not be
659*6777b538SAndroid Build Coastguard Worker     // dereferenced.
660*6777b538SAndroid Build Coastguard Worker     iterator end();
661*6777b538SAndroid Build Coastguard Worker     const_iterator end() const;
662*6777b538SAndroid Build Coastguard Worker     const_iterator cend() const;
663*6777b538SAndroid Build Coastguard Worker 
664*6777b538SAndroid Build Coastguard Worker     // Returns a reverse iterator preceding the first value in this list. May
665*6777b538SAndroid Build Coastguard Worker     // not be dereferenced.
666*6777b538SAndroid Build Coastguard Worker     reverse_iterator rend();
667*6777b538SAndroid Build Coastguard Worker     const_reverse_iterator rend() const;
668*6777b538SAndroid Build Coastguard Worker 
669*6777b538SAndroid Build Coastguard Worker     // Returns a reverse iterator to the last value in this list.
670*6777b538SAndroid Build Coastguard Worker     reverse_iterator rbegin();
671*6777b538SAndroid Build Coastguard Worker     const_reverse_iterator rbegin() const;
672*6777b538SAndroid Build Coastguard Worker 
673*6777b538SAndroid Build Coastguard Worker     // Returns a reference to the first value in the container. Fails with
674*6777b538SAndroid Build Coastguard Worker     // `CHECK()` if the list is empty.
675*6777b538SAndroid Build Coastguard Worker     const Value& front() const;
676*6777b538SAndroid Build Coastguard Worker     Value& front();
677*6777b538SAndroid Build Coastguard Worker 
678*6777b538SAndroid Build Coastguard Worker     // Returns a reference to the last value in the container. Fails with
679*6777b538SAndroid Build Coastguard Worker     // `CHECK()` if the list is empty.
680*6777b538SAndroid Build Coastguard Worker     const Value& back() const;
681*6777b538SAndroid Build Coastguard Worker     Value& back();
682*6777b538SAndroid Build Coastguard Worker 
683*6777b538SAndroid Build Coastguard Worker     // Increase the capacity of the backing container, but does not change
684*6777b538SAndroid Build Coastguard Worker     // the size. Assume all existing iterators will be invalidated.
685*6777b538SAndroid Build Coastguard Worker     void reserve(size_t capacity);
686*6777b538SAndroid Build Coastguard Worker 
687*6777b538SAndroid Build Coastguard Worker     // Resizes the list.
688*6777b538SAndroid Build Coastguard Worker     // If `new_size` is greater than current size, the extra elements in the
689*6777b538SAndroid Build Coastguard Worker     // back will be destroyed.
690*6777b538SAndroid Build Coastguard Worker     // If `new_size` is less than current size, new default-initialized elements
691*6777b538SAndroid Build Coastguard Worker     // will be added to the back.
692*6777b538SAndroid Build Coastguard Worker     // Assume all existing iterators will be invalidated.
693*6777b538SAndroid Build Coastguard Worker     void resize(size_t new_size);
694*6777b538SAndroid Build Coastguard Worker 
695*6777b538SAndroid Build Coastguard Worker     // Returns a reference to the value at `index` in this list. Fails with a
696*6777b538SAndroid Build Coastguard Worker     // `CHECK()` if `index >= size()`.
697*6777b538SAndroid Build Coastguard Worker     const Value& operator[](size_t index) const;
698*6777b538SAndroid Build Coastguard Worker     Value& operator[](size_t index);
699*6777b538SAndroid Build Coastguard Worker 
700*6777b538SAndroid Build Coastguard Worker     // Removes all value from this list.
701*6777b538SAndroid Build Coastguard Worker     REINITIALIZES_AFTER_MOVE void clear();
702*6777b538SAndroid Build Coastguard Worker 
703*6777b538SAndroid Build Coastguard Worker     // Removes the value referenced by `pos` in this list and returns an
704*6777b538SAndroid Build Coastguard Worker     // iterator to the value following the removed value.
705*6777b538SAndroid Build Coastguard Worker     iterator erase(iterator pos);
706*6777b538SAndroid Build Coastguard Worker     const_iterator erase(const_iterator pos);
707*6777b538SAndroid Build Coastguard Worker 
708*6777b538SAndroid Build Coastguard Worker     // Remove the values in the range [`first`, `last`). Returns iterator to the
709*6777b538SAndroid Build Coastguard Worker     // first value following the removed range, which is `last`. If `first` ==
710*6777b538SAndroid Build Coastguard Worker     // `last`, removes nothing and returns `last`.
711*6777b538SAndroid Build Coastguard Worker     iterator erase(iterator first, iterator last);
712*6777b538SAndroid Build Coastguard Worker     const_iterator erase(const_iterator first, const_iterator last);
713*6777b538SAndroid Build Coastguard Worker 
714*6777b538SAndroid Build Coastguard Worker     // Creates a deep copy of this dictionary.
715*6777b538SAndroid Build Coastguard Worker     List Clone() const;
716*6777b538SAndroid Build Coastguard Worker 
717*6777b538SAndroid Build Coastguard Worker     // Appends `value` to the end of this list.
718*6777b538SAndroid Build Coastguard Worker     void Append(Value&& value) &;
719*6777b538SAndroid Build Coastguard Worker     void Append(bool value) &;
720*6777b538SAndroid Build Coastguard Worker     template <typename T>
721*6777b538SAndroid Build Coastguard Worker     void Append(const T*) & = delete;
722*6777b538SAndroid Build Coastguard Worker     void Append(int value) &;
723*6777b538SAndroid Build Coastguard Worker     void Append(double value) &;
724*6777b538SAndroid Build Coastguard Worker     void Append(StringPiece value) &;
725*6777b538SAndroid Build Coastguard Worker     void Append(StringPiece16 value) &;
726*6777b538SAndroid Build Coastguard Worker     void Append(const char* value) &;
727*6777b538SAndroid Build Coastguard Worker     void Append(const char16_t* value) &;
728*6777b538SAndroid Build Coastguard Worker     void Append(std::string&& value) &;
729*6777b538SAndroid Build Coastguard Worker     void Append(BlobStorage&& value) &;
730*6777b538SAndroid Build Coastguard Worker     void Append(Dict&& value) &;
731*6777b538SAndroid Build Coastguard Worker     void Append(List&& value) &;
732*6777b538SAndroid Build Coastguard Worker 
733*6777b538SAndroid Build Coastguard Worker     // Rvalue overrides of the `Append` methods, which allow you to construct
734*6777b538SAndroid Build Coastguard Worker     // a `Value::List` builder-style:
735*6777b538SAndroid Build Coastguard Worker     //
736*6777b538SAndroid Build Coastguard Worker     // Value::List result =
737*6777b538SAndroid Build Coastguard Worker     //   Value::List().Append("first value").Append(2).Append(true);
738*6777b538SAndroid Build Coastguard Worker     //
739*6777b538SAndroid Build Coastguard Worker     // Each method returns a rvalue reference to `this`, so this is as efficient
740*6777b538SAndroid Build Coastguard Worker     // as stand-alone calls to `Append`, while at the same time making it harder
741*6777b538SAndroid Build Coastguard Worker     // to accidentally append to the wrong list.
742*6777b538SAndroid Build Coastguard Worker     //
743*6777b538SAndroid Build Coastguard Worker     // The equivalent code without using these builder-style methods:
744*6777b538SAndroid Build Coastguard Worker     //
745*6777b538SAndroid Build Coastguard Worker     // Value::List no_builder_example;
746*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Append("first value");
747*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Append(2);
748*6777b538SAndroid Build Coastguard Worker     // no_builder_example.Append(true);
749*6777b538SAndroid Build Coastguard Worker     //
750*6777b538SAndroid Build Coastguard Worker     List&& Append(Value&& value) &&;
751*6777b538SAndroid Build Coastguard Worker     List&& Append(bool value) &&;
752*6777b538SAndroid Build Coastguard Worker     template <typename T>
753*6777b538SAndroid Build Coastguard Worker     List&& Append(const T*) && = delete;
754*6777b538SAndroid Build Coastguard Worker     List&& Append(int value) &&;
755*6777b538SAndroid Build Coastguard Worker     List&& Append(double value) &&;
756*6777b538SAndroid Build Coastguard Worker     List&& Append(StringPiece value) &&;
757*6777b538SAndroid Build Coastguard Worker     List&& Append(StringPiece16 value) &&;
758*6777b538SAndroid Build Coastguard Worker     List&& Append(const char* value) &&;
759*6777b538SAndroid Build Coastguard Worker     List&& Append(const char16_t* value) &&;
760*6777b538SAndroid Build Coastguard Worker     List&& Append(std::string&& value) &&;
761*6777b538SAndroid Build Coastguard Worker     List&& Append(BlobStorage&& value) &&;
762*6777b538SAndroid Build Coastguard Worker     List&& Append(Dict&& value) &&;
763*6777b538SAndroid Build Coastguard Worker     List&& Append(List&& value) &&;
764*6777b538SAndroid Build Coastguard Worker 
765*6777b538SAndroid Build Coastguard Worker     // Inserts `value` before `pos` in this list. Returns an iterator to the
766*6777b538SAndroid Build Coastguard Worker     // inserted value.
767*6777b538SAndroid Build Coastguard Worker     // TODO(dcheng): Should this provide the same set of overloads that Append()
768*6777b538SAndroid Build Coastguard Worker     // does?
769*6777b538SAndroid Build Coastguard Worker     iterator Insert(const_iterator pos, Value&& value);
770*6777b538SAndroid Build Coastguard Worker 
771*6777b538SAndroid Build Coastguard Worker     // Erases all values equal to `value` from this list.
772*6777b538SAndroid Build Coastguard Worker     size_t EraseValue(const Value& value);
773*6777b538SAndroid Build Coastguard Worker 
774*6777b538SAndroid Build Coastguard Worker     // Erases all values for which `predicate` evaluates to true from this list.
775*6777b538SAndroid Build Coastguard Worker     template <typename Predicate>
EraseIf(Predicate predicate)776*6777b538SAndroid Build Coastguard Worker     size_t EraseIf(Predicate predicate) {
777*6777b538SAndroid Build Coastguard Worker       return std::erase_if(storage_, predicate);
778*6777b538SAndroid Build Coastguard Worker     }
779*6777b538SAndroid Build Coastguard Worker 
780*6777b538SAndroid Build Coastguard Worker     // Estimates dynamic memory usage. Requires tracing support
781*6777b538SAndroid Build Coastguard Worker     // (enable_base_tracing gn flag), otherwise always returns 0. See
782*6777b538SAndroid Build Coastguard Worker     // base/trace_event/memory_usage_estimator.h for more info.
783*6777b538SAndroid Build Coastguard Worker     size_t EstimateMemoryUsage() const;
784*6777b538SAndroid Build Coastguard Worker 
785*6777b538SAndroid Build Coastguard Worker     // Serializes to a string for logging and debug purposes.
786*6777b538SAndroid Build Coastguard Worker     std::string DebugString() const;
787*6777b538SAndroid Build Coastguard Worker 
788*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
789*6777b538SAndroid Build Coastguard Worker     // Write this object into a trace.
790*6777b538SAndroid Build Coastguard Worker     void WriteIntoTrace(perfetto::TracedValue) const;
791*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
792*6777b538SAndroid Build Coastguard Worker 
793*6777b538SAndroid Build Coastguard Worker    private:
794*6777b538SAndroid Build Coastguard Worker     using ListStorage = std::vector<Value>;
795*6777b538SAndroid Build Coastguard Worker 
796*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
797*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
798*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
799*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
800*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
801*6777b538SAndroid Build Coastguard Worker     BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);
802*6777b538SAndroid Build Coastguard Worker 
803*6777b538SAndroid Build Coastguard Worker     explicit List(const std::vector<Value>& storage);
804*6777b538SAndroid Build Coastguard Worker 
805*6777b538SAndroid Build Coastguard Worker     std::vector<Value> storage_;
806*6777b538SAndroid Build Coastguard Worker   };
807*6777b538SAndroid Build Coastguard Worker 
808*6777b538SAndroid Build Coastguard Worker   // Note: Do not add more types. See the file-level comment above for why.
809*6777b538SAndroid Build Coastguard Worker 
810*6777b538SAndroid Build Coastguard Worker   // Comparison operators so that Values can easily be used with standard
811*6777b538SAndroid Build Coastguard Worker   // library algorithms and associative containers.
812*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
813*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs);
814*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs);
815*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs);
816*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
817*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);
818*6777b538SAndroid Build Coastguard Worker 
819*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs);
820*6777b538SAndroid Build Coastguard Worker   friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; }
821*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); }
822*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); }
823*6777b538SAndroid Build Coastguard Worker   template <typename T>
824*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const Value& lhs, const T* rhs) = delete;
825*6777b538SAndroid Build Coastguard Worker   template <typename T>
826*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const T* lhs, const Value& rhs) = delete;
827*6777b538SAndroid Build Coastguard Worker   template <typename T>
828*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, const T* rhs) = delete;
829*6777b538SAndroid Build Coastguard Worker   template <typename T>
830*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const T* lhs, const Value& rhs) = delete;
831*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, int rhs);
832*6777b538SAndroid Build Coastguard Worker   friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; }
833*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); }
834*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); }
835*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, double rhs);
836*6777b538SAndroid Build Coastguard Worker   friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; }
837*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); }
838*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); }
839*6777b538SAndroid Build Coastguard Worker   // Note: StringPiece16 overload intentionally omitted: Value internally stores
840*6777b538SAndroid Build Coastguard Worker   // strings as UTF-8. While it is possible to implement a comparison operator
841*6777b538SAndroid Build Coastguard Worker   // that would not require first creating a new UTF-8 string from the UTF-16
842*6777b538SAndroid Build Coastguard Worker   // string argument, it is simpler to just not implement it at all for a rare
843*6777b538SAndroid Build Coastguard Worker   // use case.
844*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs);
845*6777b538SAndroid Build Coastguard Worker   friend bool operator==(StringPiece lhs, const Value& rhs) {
846*6777b538SAndroid Build Coastguard Worker     return rhs == lhs;
847*6777b538SAndroid Build Coastguard Worker   }
848*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, StringPiece rhs) {
849*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
850*6777b538SAndroid Build Coastguard Worker   }
851*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(StringPiece lhs, const Value& rhs) {
852*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
853*6777b538SAndroid Build Coastguard Worker   }
854*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const Value& lhs, const char* rhs) {
855*6777b538SAndroid Build Coastguard Worker     return lhs == StringPiece(rhs);
856*6777b538SAndroid Build Coastguard Worker   }
857*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const char* lhs, const Value& rhs) {
858*6777b538SAndroid Build Coastguard Worker     return rhs == lhs;
859*6777b538SAndroid Build Coastguard Worker   }
860*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, const char* rhs) {
861*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
862*6777b538SAndroid Build Coastguard Worker   }
863*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const char* lhs, const Value& rhs) {
864*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
865*6777b538SAndroid Build Coastguard Worker   }
866*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const Value& lhs, const std::string& rhs) {
867*6777b538SAndroid Build Coastguard Worker     return lhs == StringPiece(rhs);
868*6777b538SAndroid Build Coastguard Worker   }
869*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const std::string& lhs, const Value& rhs) {
870*6777b538SAndroid Build Coastguard Worker     return rhs == lhs;
871*6777b538SAndroid Build Coastguard Worker   }
872*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, const std::string& rhs) {
873*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
874*6777b538SAndroid Build Coastguard Worker   }
875*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const std::string& lhs, const Value& rhs) {
876*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
877*6777b538SAndroid Build Coastguard Worker   }
878*6777b538SAndroid Build Coastguard Worker   // Note: Blob support intentionally omitted as an experiment for potentially
879*6777b538SAndroid Build Coastguard Worker   // wholly removing Blob support from Value itself in the future.
880*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs);
881*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const Value::Dict& lhs, const Value& rhs) {
882*6777b538SAndroid Build Coastguard Worker     return rhs == lhs;
883*6777b538SAndroid Build Coastguard Worker   }
884*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, const Value::Dict& rhs) {
885*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
886*6777b538SAndroid Build Coastguard Worker   }
887*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value::Dict& lhs, const Value& rhs) {
888*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
889*6777b538SAndroid Build Coastguard Worker   }
890*6777b538SAndroid Build Coastguard Worker   BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs);
891*6777b538SAndroid Build Coastguard Worker   friend bool operator==(const Value::List& lhs, const Value& rhs) {
892*6777b538SAndroid Build Coastguard Worker     return rhs == lhs;
893*6777b538SAndroid Build Coastguard Worker   }
894*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value& lhs, const Value::List& rhs) {
895*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
896*6777b538SAndroid Build Coastguard Worker   }
897*6777b538SAndroid Build Coastguard Worker   friend bool operator!=(const Value::List& lhs, const Value& rhs) {
898*6777b538SAndroid Build Coastguard Worker     return !(lhs == rhs);
899*6777b538SAndroid Build Coastguard Worker   }
900*6777b538SAndroid Build Coastguard Worker 
901*6777b538SAndroid Build Coastguard Worker   // Estimates dynamic memory usage. Requires tracing support
902*6777b538SAndroid Build Coastguard Worker   // (enable_base_tracing gn flag), otherwise always returns 0. See
903*6777b538SAndroid Build Coastguard Worker   // base/trace_event/memory_usage_estimator.h for more info.
904*6777b538SAndroid Build Coastguard Worker   size_t EstimateMemoryUsage() const;
905*6777b538SAndroid Build Coastguard Worker 
906*6777b538SAndroid Build Coastguard Worker   // Serializes to a string for logging and debug purposes.
907*6777b538SAndroid Build Coastguard Worker   std::string DebugString() const;
908*6777b538SAndroid Build Coastguard Worker 
909*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING)
910*6777b538SAndroid Build Coastguard Worker   // Write this object into a trace.
911*6777b538SAndroid Build Coastguard Worker   void WriteIntoTrace(perfetto::TracedValue) const;
912*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
913*6777b538SAndroid Build Coastguard Worker 
914*6777b538SAndroid Build Coastguard Worker   template <typename Visitor>
Visit(Visitor && visitor)915*6777b538SAndroid Build Coastguard Worker   auto Visit(Visitor&& visitor) const {
916*6777b538SAndroid Build Coastguard Worker     return absl::visit(std::forward<Visitor>(visitor), data_);
917*6777b538SAndroid Build Coastguard Worker   }
918*6777b538SAndroid Build Coastguard Worker 
919*6777b538SAndroid Build Coastguard Worker  private:
920*6777b538SAndroid Build Coastguard Worker   // For access to DoubleStorage.
921*6777b538SAndroid Build Coastguard Worker   friend class ValueView;
922*6777b538SAndroid Build Coastguard Worker 
923*6777b538SAndroid Build Coastguard Worker   // Special case for doubles, which are aligned to 8 bytes on some
924*6777b538SAndroid Build Coastguard Worker   // 32-bit architectures. In this case, a simple declaration as a
925*6777b538SAndroid Build Coastguard Worker   // double member would make the whole union 8 byte-aligned, which
926*6777b538SAndroid Build Coastguard Worker   // would also force 4 bytes of wasted padding space before it in
927*6777b538SAndroid Build Coastguard Worker   // the Value layout.
928*6777b538SAndroid Build Coastguard Worker   //
929*6777b538SAndroid Build Coastguard Worker   // To override this, store the value as an array of 32-bit integers, and
930*6777b538SAndroid Build Coastguard Worker   // perform the appropriate bit casts when reading / writing to it.
931*6777b538SAndroid Build Coastguard Worker   class BASE_EXPORT DoubleStorage {
932*6777b538SAndroid Build Coastguard Worker    public:
933*6777b538SAndroid Build Coastguard Worker     explicit DoubleStorage(double v);
934*6777b538SAndroid Build Coastguard Worker     DoubleStorage(const DoubleStorage&) = default;
935*6777b538SAndroid Build Coastguard Worker     DoubleStorage& operator=(const DoubleStorage&) = default;
936*6777b538SAndroid Build Coastguard Worker 
937*6777b538SAndroid Build Coastguard Worker     // Provide an implicit conversion to double to simplify the use of visitors
938*6777b538SAndroid Build Coastguard Worker     // with `Value::Visit()`. Otherwise, visitors would need a branch for
939*6777b538SAndroid Build Coastguard Worker     // handling `DoubleStorage` like:
940*6777b538SAndroid Build Coastguard Worker     //
941*6777b538SAndroid Build Coastguard Worker     //   value.Visit([] (const auto& member) {
942*6777b538SAndroid Build Coastguard Worker     //     using T = std::decay_t<decltype(member)>;
943*6777b538SAndroid Build Coastguard Worker     //     if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
944*6777b538SAndroid Build Coastguard Worker     //       SomeFunction(double{member});
945*6777b538SAndroid Build Coastguard Worker     //     } else {
946*6777b538SAndroid Build Coastguard Worker     //       SomeFunction(member);
947*6777b538SAndroid Build Coastguard Worker     //     }
948*6777b538SAndroid Build Coastguard Worker     //   });
949*6777b538SAndroid Build Coastguard Worker     operator double() const { return base::bit_cast<double>(v_); }
950*6777b538SAndroid Build Coastguard Worker 
951*6777b538SAndroid Build Coastguard Worker    private:
952*6777b538SAndroid Build Coastguard Worker     friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
953*6777b538SAndroid Build Coastguard Worker       return double{lhs} == double{rhs};
954*6777b538SAndroid Build Coastguard Worker     }
955*6777b538SAndroid Build Coastguard Worker 
956*6777b538SAndroid Build Coastguard Worker     friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
957*6777b538SAndroid Build Coastguard Worker       return !(lhs == rhs);
958*6777b538SAndroid Build Coastguard Worker     }
959*6777b538SAndroid Build Coastguard Worker 
960*6777b538SAndroid Build Coastguard Worker     friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
961*6777b538SAndroid Build Coastguard Worker       return double{lhs} < double{rhs};
962*6777b538SAndroid Build Coastguard Worker     }
963*6777b538SAndroid Build Coastguard Worker 
964*6777b538SAndroid Build Coastguard Worker     friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
965*6777b538SAndroid Build Coastguard Worker       return rhs < lhs;
966*6777b538SAndroid Build Coastguard Worker     }
967*6777b538SAndroid Build Coastguard Worker 
968*6777b538SAndroid Build Coastguard Worker     friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
969*6777b538SAndroid Build Coastguard Worker       return !(rhs < lhs);
970*6777b538SAndroid Build Coastguard Worker     }
971*6777b538SAndroid Build Coastguard Worker 
972*6777b538SAndroid Build Coastguard Worker     friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
973*6777b538SAndroid Build Coastguard Worker       return !(lhs < rhs);
974*6777b538SAndroid Build Coastguard Worker     }
975*6777b538SAndroid Build Coastguard Worker 
976*6777b538SAndroid Build Coastguard Worker     alignas(4) std::array<char, sizeof(double)> v_;
977*6777b538SAndroid Build Coastguard Worker   };
978*6777b538SAndroid Build Coastguard Worker 
979*6777b538SAndroid Build Coastguard Worker   // Internal constructors, allowing the simplify the implementation of Clone().
980*6777b538SAndroid Build Coastguard Worker   explicit Value(absl::monostate);
981*6777b538SAndroid Build Coastguard Worker   explicit Value(DoubleStorage storage);
982*6777b538SAndroid Build Coastguard Worker 
983*6777b538SAndroid Build Coastguard Worker   // A helper for static functions used for cloning a Value or a ValueView.
984*6777b538SAndroid Build Coastguard Worker   class CloningHelper;
985*6777b538SAndroid Build Coastguard Worker 
986*6777b538SAndroid Build Coastguard Worker   absl::variant<absl::monostate,
987*6777b538SAndroid Build Coastguard Worker                 bool,
988*6777b538SAndroid Build Coastguard Worker                 int,
989*6777b538SAndroid Build Coastguard Worker                 DoubleStorage,
990*6777b538SAndroid Build Coastguard Worker                 std::string,
991*6777b538SAndroid Build Coastguard Worker                 BlobStorage,
992*6777b538SAndroid Build Coastguard Worker                 Dict,
993*6777b538SAndroid Build Coastguard Worker                 List>
994*6777b538SAndroid Build Coastguard Worker       data_;
995*6777b538SAndroid Build Coastguard Worker };
996*6777b538SAndroid Build Coastguard Worker 
997*6777b538SAndroid Build Coastguard Worker // Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
998*6777b538SAndroid Build Coastguard Worker // serialization methods without having to clone the contents and transfer
999*6777b538SAndroid Build Coastguard Worker // ownership of the clone to a `Value` wrapper object.
1000*6777b538SAndroid Build Coastguard Worker //
1001*6777b538SAndroid Build Coastguard Worker // Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
1002*6777b538SAndroid Build Coastguard Worker // underlying object that is passed by reference (i.e. `std::string`,
1003*6777b538SAndroid Build Coastguard Worker // `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
1004*6777b538SAndroid Build Coastguard Worker // live as long as there is a `ValueView` referencing it.
1005*6777b538SAndroid Build Coastguard Worker //
1006*6777b538SAndroid Build Coastguard Worker // While it might be nice to just use the `absl::variant` type directly, the
1007*6777b538SAndroid Build Coastguard Worker // need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
1008*6777b538SAndroid Build Coastguard Worker // `std::reference_wrapper` both support implicit construction, but C++ only
1009*6777b538SAndroid Build Coastguard Worker // allows at most one user-defined conversion in an implicit conversion
1010*6777b538SAndroid Build Coastguard Worker // sequence. If this adapter and its implicit constructors did not exist,
1011*6777b538SAndroid Build Coastguard Worker // callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
1012*6777b538SAndroid Build Coastguard Worker // `Value::List` to a function with a `ValueView` parameter.
1013*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT GSL_POINTER ValueView {
1014*6777b538SAndroid Build Coastguard Worker  public:
1015*6777b538SAndroid Build Coastguard Worker   ValueView() = default;
ValueView(bool value)1016*6777b538SAndroid Build Coastguard Worker   ValueView(bool value) : data_view_(value) {}
1017*6777b538SAndroid Build Coastguard Worker   template <typename T>
1018*6777b538SAndroid Build Coastguard Worker   ValueView(const T*) = delete;
ValueView(int value)1019*6777b538SAndroid Build Coastguard Worker   ValueView(int value) : data_view_(value) {}
ValueView(double value)1020*6777b538SAndroid Build Coastguard Worker   ValueView(double value)
1021*6777b538SAndroid Build Coastguard Worker       : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
ValueView(StringPiece value)1022*6777b538SAndroid Build Coastguard Worker   ValueView(StringPiece value) : data_view_(value) {}
ValueView(const char * value)1023*6777b538SAndroid Build Coastguard Worker   ValueView(const char* value) : ValueView(StringPiece(value)) {}
ValueView(const std::string & value)1024*6777b538SAndroid Build Coastguard Worker   ValueView(const std::string& value) : ValueView(StringPiece(value)) {}
1025*6777b538SAndroid Build Coastguard Worker   // Note: UTF-16 is intentionally not supported. ValueView is intended to be a
1026*6777b538SAndroid Build Coastguard Worker   // low-cost view abstraction, but Value internally represents strings as
1027*6777b538SAndroid Build Coastguard Worker   // UTF-8, so it would not be possible to implement this without allocating an
1028*6777b538SAndroid Build Coastguard Worker   // entirely new UTF-8 string.
ValueView(const Value::BlobStorage & value)1029*6777b538SAndroid Build Coastguard Worker   ValueView(const Value::BlobStorage& value) : data_view_(value) {}
ValueView(const Value::Dict & value)1030*6777b538SAndroid Build Coastguard Worker   ValueView(const Value::Dict& value) : data_view_(value) {}
ValueView(const Value::List & value)1031*6777b538SAndroid Build Coastguard Worker   ValueView(const Value::List& value) : data_view_(value) {}
1032*6777b538SAndroid Build Coastguard Worker   ValueView(const Value& value);
1033*6777b538SAndroid Build Coastguard Worker 
1034*6777b538SAndroid Build Coastguard Worker   // This is the only 'getter' method provided as `ValueView` is not intended
1035*6777b538SAndroid Build Coastguard Worker   // to be a general replacement of `Value`.
1036*6777b538SAndroid Build Coastguard Worker   template <typename Visitor>
Visit(Visitor && visitor)1037*6777b538SAndroid Build Coastguard Worker   auto Visit(Visitor&& visitor) const {
1038*6777b538SAndroid Build Coastguard Worker     return absl::visit(std::forward<Visitor>(visitor), data_view_);
1039*6777b538SAndroid Build Coastguard Worker   }
1040*6777b538SAndroid Build Coastguard Worker 
1041*6777b538SAndroid Build Coastguard Worker   // Returns a clone of the underlying Value.
1042*6777b538SAndroid Build Coastguard Worker   Value ToValue() const;
1043*6777b538SAndroid Build Coastguard Worker 
1044*6777b538SAndroid Build Coastguard Worker  private:
1045*6777b538SAndroid Build Coastguard Worker   using ViewType =
1046*6777b538SAndroid Build Coastguard Worker       absl::variant<absl::monostate,
1047*6777b538SAndroid Build Coastguard Worker                     bool,
1048*6777b538SAndroid Build Coastguard Worker                     int,
1049*6777b538SAndroid Build Coastguard Worker                     Value::DoubleStorage,
1050*6777b538SAndroid Build Coastguard Worker                     StringPiece,
1051*6777b538SAndroid Build Coastguard Worker                     std::reference_wrapper<const Value::BlobStorage>,
1052*6777b538SAndroid Build Coastguard Worker                     std::reference_wrapper<const Value::Dict>,
1053*6777b538SAndroid Build Coastguard Worker                     std::reference_wrapper<const Value::List>>;
1054*6777b538SAndroid Build Coastguard Worker 
1055*6777b538SAndroid Build Coastguard Worker  public:
1056*6777b538SAndroid Build Coastguard Worker   using DoubleStorageForTest = Value::DoubleStorage;
data_view_for_test()1057*6777b538SAndroid Build Coastguard Worker   const ViewType& data_view_for_test() const { return data_view_; }
1058*6777b538SAndroid Build Coastguard Worker 
1059*6777b538SAndroid Build Coastguard Worker  private:
1060*6777b538SAndroid Build Coastguard Worker   ViewType data_view_;
1061*6777b538SAndroid Build Coastguard Worker };
1062*6777b538SAndroid Build Coastguard Worker 
1063*6777b538SAndroid Build Coastguard Worker // This interface is implemented by classes that know how to serialize
1064*6777b538SAndroid Build Coastguard Worker // Value objects.
1065*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ValueSerializer {
1066*6777b538SAndroid Build Coastguard Worker  public:
1067*6777b538SAndroid Build Coastguard Worker   virtual ~ValueSerializer();
1068*6777b538SAndroid Build Coastguard Worker 
1069*6777b538SAndroid Build Coastguard Worker   virtual bool Serialize(ValueView root) = 0;
1070*6777b538SAndroid Build Coastguard Worker };
1071*6777b538SAndroid Build Coastguard Worker 
1072*6777b538SAndroid Build Coastguard Worker // This interface is implemented by classes that know how to deserialize Value
1073*6777b538SAndroid Build Coastguard Worker // objects.
1074*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ValueDeserializer {
1075*6777b538SAndroid Build Coastguard Worker  public:
1076*6777b538SAndroid Build Coastguard Worker   virtual ~ValueDeserializer();
1077*6777b538SAndroid Build Coastguard Worker 
1078*6777b538SAndroid Build Coastguard Worker   // This method deserializes the subclass-specific format into a Value object.
1079*6777b538SAndroid Build Coastguard Worker   // If the return value is non-NULL, the caller takes ownership of returned
1080*6777b538SAndroid Build Coastguard Worker   // Value.
1081*6777b538SAndroid Build Coastguard Worker   //
1082*6777b538SAndroid Build Coastguard Worker   // If the return value is nullptr, and if `error_code` is non-nullptr,
1083*6777b538SAndroid Build Coastguard Worker   // `*error_code` will be set to an integer value representing the underlying
1084*6777b538SAndroid Build Coastguard Worker   // error. See "enum ErrorCode" below for more detail about the integer value.
1085*6777b538SAndroid Build Coastguard Worker   //
1086*6777b538SAndroid Build Coastguard Worker   // If `error_message` is non-nullptr, it will be filled in with a formatted
1087*6777b538SAndroid Build Coastguard Worker   // error message including the location of the error if appropriate.
1088*6777b538SAndroid Build Coastguard Worker   virtual std::unique_ptr<Value> Deserialize(int* error_code,
1089*6777b538SAndroid Build Coastguard Worker                                              std::string* error_message) = 0;
1090*6777b538SAndroid Build Coastguard Worker 
1091*6777b538SAndroid Build Coastguard Worker   // The integer-valued error codes form four groups:
1092*6777b538SAndroid Build Coastguard Worker   //  - The value 0 means no error.
1093*6777b538SAndroid Build Coastguard Worker   //  - Values between 1 and 999 inclusive mean an error in the data (i.e.
1094*6777b538SAndroid Build Coastguard Worker   //    content). The bytes being deserialized are not in the right format.
1095*6777b538SAndroid Build Coastguard Worker   //  - Values 1000 and above mean an error in the metadata (i.e. context). The
1096*6777b538SAndroid Build Coastguard Worker   //    file could not be read, the network is down, etc.
1097*6777b538SAndroid Build Coastguard Worker   //  - Negative values are reserved.
1098*6777b538SAndroid Build Coastguard Worker   //
1099*6777b538SAndroid Build Coastguard Worker   // These values are persisted to logs. Entries should not be renumbered and
1100*6777b538SAndroid Build Coastguard Worker   // numeric values should never be reused.
1101*6777b538SAndroid Build Coastguard Worker   enum ErrorCode {
1102*6777b538SAndroid Build Coastguard Worker     kErrorCodeNoError = 0,
1103*6777b538SAndroid Build Coastguard Worker     // kErrorCodeInvalidFormat is a generic error code for "the data is not in
1104*6777b538SAndroid Build Coastguard Worker     // the right format". Subclasses of ValueDeserializer may return other
1105*6777b538SAndroid Build Coastguard Worker     // values for more specific errors.
1106*6777b538SAndroid Build Coastguard Worker     kErrorCodeInvalidFormat = 1,
1107*6777b538SAndroid Build Coastguard Worker     // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
1108*6777b538SAndroid Build Coastguard Worker     // range of metadata errors.
1109*6777b538SAndroid Build Coastguard Worker     kErrorCodeFirstMetadataError = 1000,
1110*6777b538SAndroid Build Coastguard Worker   };
1111*6777b538SAndroid Build Coastguard Worker 
1112*6777b538SAndroid Build Coastguard Worker   // The `error_code` argument can be one of the ErrorCode values, but it is
1113*6777b538SAndroid Build Coastguard Worker   // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
1114*6777b538SAndroid Build Coastguard Worker   // can define their own error code values.
ErrorCodeIsDataError(int error_code)1115*6777b538SAndroid Build Coastguard Worker   static inline bool ErrorCodeIsDataError(int error_code) {
1116*6777b538SAndroid Build Coastguard Worker     return (kErrorCodeInvalidFormat <= error_code) &&
1117*6777b538SAndroid Build Coastguard Worker            (error_code < kErrorCodeFirstMetadataError);
1118*6777b538SAndroid Build Coastguard Worker   }
1119*6777b538SAndroid Build Coastguard Worker };
1120*6777b538SAndroid Build Coastguard Worker 
1121*6777b538SAndroid Build Coastguard Worker // Stream operator so Values can be pretty printed by gtest.
1122*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
1123*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1124*6777b538SAndroid Build Coastguard Worker                                      const Value::Dict& dict);
1125*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1126*6777b538SAndroid Build Coastguard Worker                                      const Value::List& list);
1127*6777b538SAndroid Build Coastguard Worker 
1128*6777b538SAndroid Build Coastguard Worker // Stream operator so that enum class Types can be used in log statements.
1129*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1130*6777b538SAndroid Build Coastguard Worker                                      const Value::Type& type);
1131*6777b538SAndroid Build Coastguard Worker 
1132*6777b538SAndroid Build Coastguard Worker }  // namespace base
1133*6777b538SAndroid Build Coastguard Worker 
1134*6777b538SAndroid Build Coastguard Worker #endif  // BASE_VALUES_H_
1135