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