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