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.
12 #include <initializer_list>
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/checked_range.h"
25 #include "base/containers/cxx20_erase_vector.h"
26 #include "base/containers/flat_map.h"
27 #include "base/containers/span.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"
36 class DictAdapterForMigration;
37 class DictionaryValue;
40 // The `Value` class is a variant type can hold one of the following types:
45 // - string (internally UTF8-encoded)
46 // - binary data (i.e. a blob)
47 // - dictionary of string keys to `Value`s
50 // With the exception of binary blobs, `Value` is intended to be the C++ version
51 // of data types that can be represented in JSON.
53 // Warning: blob support may be removed in the future.
57 // Do not use `Value` if a more specific type would be more appropriate. For
58 // example, a function that only accepts dictionary values should have a
59 // `base::Value::Dict` parameter, not a `base::Value` parameter.
63 // `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
64 // (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
65 // `Value::Dict`, and `Value::List`.
69 // `Value` does not support C++ copy semantics to make it harder to accidentally
70 // copy large values. Instead, use `Clone()` to manually create a deep copy.
74 // `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
75 // subtype before returning the contained value. `bool`, `int`, `double` are
76 // returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
77 // are returned by reference.
79 // `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
80 // the `Value` does not have the correct subtype; otherwise, returns the value
81 // wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
82 // (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
84 // Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
85 // when the subtype is `Value::Type::INT`. In that case, the stored value is
86 // coerced to a double before being returned.
90 // It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
91 // Instead, wrap the underlying type in `Value` before assigning.
93 // ## Dictionaries and Lists
95 // `Value` provides the `Value::Dict` and `Value::List` container types for
96 // working with dictionaries and lists of values respectively, rather than
97 // exposing the underlying container types directly. This allows the types to
98 // provide convenient helpers for dictionaries and lists, as well as giving
99 // greater flexibility for changing implementation details in the future.
101 // Both container types support enough STL-isms to be usable in range-based for
102 // loops and generic operations such as those from <algorithm>.
104 // Dictionaries support:
105 // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
106 // `contains()`, `clear()`, `erase()`: Identical to the STL container
107 // equivalents, with additional safety checks, e.g. iterators will
108 // `CHECK()` if `end()` is dereferenced.
110 // - `Clone()`: Create a deep copy.
111 // - `Merge()`: Merge another dictionary into this dictionary.
112 // - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
114 // - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
115 // `Value` also has the correct subtype. Same return semantics as
116 // `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
117 // `nullptr` if the key is not present or the value has the wrong subtype.
118 // - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
119 // of the subtypes that `Value` can hold.
120 // - `Remove()`: Remove the key from this dictionary, if present.
121 // - `Extract()`: If the key is present in the dictionary, removes the key from
122 // the dictionary and transfers ownership of `Value` to the caller.
123 // Otherwise, returns `absl::nullopt`.
125 // Dictionaries also support an additional set of helper methods that operate on
126 // "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
127 // and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
128 // intermediate nested dictionaries, separating the components of the path using
129 // '.' characters. For example, finding a string path on a `Value::Dict` using
134 // Will first look for a `Value::Type::DICT` associated with the key "aaa", then
135 // another `Value::Type::DICT` under the "aaa" dict associated with the
136 // key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
137 // with the key "ccc".
139 // If a path only has one component (i.e. has no dots), please use the regular,
143 // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
144 // `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`:
145 // Identical to the STL container equivalents, with additional safety
146 // checks, e.g. `operator[]` will `CHECK()` if the index is out of range.
147 // - `Clone()`: Create a deep copy.
148 // - `Append()`: Append a value to the end of the list. Accepts `Value` or any
149 // of the subtypes that `Value` can hold.
150 // - `Insert()`: Insert a `Value` at a specified point in the list.
151 // - `EraseValue()`: Erases all matching `Value`s from the list.
152 // - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
155 // ## Refactoring Notes
157 // `Value` was originally implemented as a class hierarchy, with a `Value` base
158 // class, and a leaf class for each of the different types of `Value` subtypes.
159 // https://docs.google.com/document/d/1uDLu5uTRlCWePxQUEHc8yNQdEoE1BDISYdpggWEABnw
160 // proposed an overhaul of the `Value` API that has now largely been
161 // implemented, though there remains a significant amount of legacy code that is
162 // still being migrated as part of the code health migration.
166 // std::unique_ptr<base::Value> GetFoo() {
167 // std::unique_ptr<DictionaryValue> dict;
168 // dict->SetString("mykey", "foo");
174 // base::Value GetFoo() {
175 // base::Value::Dict dict;
176 // dict.Set("mykey", "abc");
177 // return base::Value(std::move(dict));
180 // To avoid losing type information with the new variant-based design, migration
181 // off the deprecated types should use more specific subtypes where possible:
185 // void AlwaysTakesList(std::unique_ptr<base::ListValue> list);
186 // void AlwaysTakesDict(std::unique_ptr<base::DictionaryValue> dict);
188 // DEPRECATED (PREVIOUS) WAY:
190 // void AlwaysTakesList(std::vector<base::Value> list);
191 // void AlwaysTakesListAlternative1(base::Value::ConstListView list);
192 // void AlwaysTakesListAlternative2(base::Value::ListView& list);
193 // void AlwaysTakesListAlterantive3(base::Value::ListStorage);
194 // void AlwaysTakesDict(base::flat_map<std::string, base::Value> dict);
195 // void AlwaysTakesDictAlternative(base::Value::DictStorage);
199 // void AlwaysTakesList(base::Value::List list);
200 // void AlwaysTakesDict(base::Value::Dict dict);
202 // Migrating code may require conversions on API boundaries. If something seems
203 // awkward/inefficient, please reach out to #code-health-rotation on Slack for
204 // consultation: it is entirely possible that certain classes of APIs may be
205 // missing due to an unrealized need.
206 class BASE_EXPORT GSL_OWNER Value {
208 using BlobStorage = std::vector<uint8_t>;
210 using DeprecatedListStorage = std::vector<Value>;
212 // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is
213 // due to legacy reasons, and should be replaced with
214 // flat_map<std::string, Value> once no caller relies on stability of pointers
216 using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>;
218 using DeprecatedListView = CheckedContiguousRange<DeprecatedListStorage>;
219 using DeprecatedConstListView =
220 CheckedContiguousConstRange<DeprecatedListStorage>;
221 // TODO(https://crbug.com/1291666): Make these private.
222 using ListView = DeprecatedListView;
223 using ConstListView = DeprecatedConstListView;
228 enum class Type : unsigned char {
236 // TODO(https://crbug.com/1291670): Deprecated and will be removed.
239 // Note: Do not add more types. See the file-level comment above for why.
242 // Adaptors for converting from the old way to the new way and vice versa.
243 static Value FromUniquePtrValue(std::unique_ptr<Value> val);
244 static std::unique_ptr<Value> ToUniquePtrValue(Value val);
245 static const DictionaryValue& AsDictionaryValue(const Value& val);
246 static const ListValue& AsListValue(const Value& val);
250 Value(Value&&) noexcept;
251 Value& operator=(Value&&) noexcept;
253 // Deleted to prevent accidental copying.
254 Value(const Value&) = delete;
255 Value& operator=(const Value&) = delete;
257 // Creates a deep copy of this value.
260 // Creates a `Value` of `type`. The data of the corresponding type will be
261 // default constructed.
262 explicit Value(Type type);
264 // Constructor for `Value::Type::BOOLEAN`.
265 explicit Value(bool value);
267 // Prevent pointers from implicitly converting to bool. Another way to write
268 // this would be to template the bool constructor and use SFINAE to only allow
269 // use if `std::is_same_v<T, bool>` is true, but this has surprising behavior
270 // with range-based for loops over a `std::vector<bool>` (which will
271 // unintuitively match the int overload instead).
273 // The `const` is load-bearing; otherwise, a `char*` argument would prefer the
274 // deleted overload due to requiring a qualification conversion.
275 template <typename T>
276 explicit Value(const T*) = delete;
278 // Constructor for `Value::Type::INT`.
279 explicit Value(int value);
281 // Constructor for `Value::Type::DOUBLE`.
282 explicit Value(double value);
284 // Constructors for `Value::Type::STRING`.
285 explicit Value(StringPiece value);
286 explicit Value(StringPiece16 value);
287 // `char*` and `char16_t*` are needed to provide a more specific overload than
288 // the deleted `const T*` overload above.
289 explicit Value(const char* value);
290 explicit Value(const char16_t* value);
291 // `std::string&&` allows for efficient move construction.
292 explicit Value(std::string&& value) noexcept;
294 // Constructors for `Value::Type::BINARY`.
295 explicit Value(const std::vector<char>& value);
296 explicit Value(base::span<const uint8_t> value);
297 explicit Value(BlobStorage&& value) noexcept;
299 // Constructor for `Value::Type::DICT`.
300 explicit Value(Dict&& value) noexcept;
302 // Constructor for `Value::Type::LIST`.
303 explicit Value(List&& value) noexcept;
307 // Returns the name for a given `type`.
308 static const char* GetTypeName(Type type);
310 // Returns the type of the value stored by the current Value object.
311 Type type() const { return static_cast<Type>(data_.index()); }
313 // Returns true if the current object represents a given type.
314 bool is_none() const { return type() == Type::NONE; }
315 bool is_bool() const { return type() == Type::BOOLEAN; }
316 bool is_int() const { return type() == Type::INTEGER; }
317 bool is_double() const { return type() == Type::DOUBLE; }
318 bool is_string() const { return type() == Type::STRING; }
319 bool is_blob() const { return type() == Type::BINARY; }
320 bool is_dict() const { return type() == Type::DICT; }
321 bool is_list() const { return type() == Type::LIST; }
323 // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
324 // otherwise. `bool`, `int`, and `double` are returned in a wrapped
325 // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
327 absl::optional<bool> GetIfBool() const;
328 absl::optional<int> GetIfInt() const;
329 // Returns a non-null value for both `Value::Type::DOUBLE` and
330 // `Value::Type::INT`, converting the latter to a double.
331 absl::optional<double> GetIfDouble() const;
332 const std::string* GetIfString() const;
333 std::string* GetIfString();
334 const BlobStorage* GetIfBlob() const;
335 const Dict* GetIfDict() const;
337 const List* GetIfList() const;
340 // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
341 // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
342 // `Value::Dict`, and `Value::List` are returned by reference.
343 bool GetBool() const;
345 // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
346 // converting the latter to a double.
347 double GetDouble() const;
348 const std::string& GetString() const;
349 std::string& GetString();
350 const BlobStorage& GetBlob() const;
351 const Dict& GetDict() const;
353 const List& GetList() const;
356 // Transfers ownership of the underlying value. Similarly to `Get...()`
357 // variants above, fails with a `CHECK()` on a type mismatch. After
358 // transferring the ownership `*this` is in a valid, but unspecified, state.
359 // Prefer over `std::move(value.Get...())` so clang-tidy can warn about
360 // potential use-after-move mistakes.
361 std::string TakeString() &&;
365 // Represents a dictionary of string keys to Values.
366 class BASE_EXPORT GSL_OWNER Dict {
368 using iterator = detail::dict_iterator;
369 using const_iterator = detail::const_dict_iterator;
373 Dict(Dict&&) noexcept;
374 Dict& operator=(Dict&&) noexcept;
376 // Deleted to prevent accidental copying.
377 Dict(const Dict&) = delete;
378 Dict& operator=(const Dict&) = delete;
380 // Takes move_iterators iterators that return std::pair<std::string, Value>,
381 // and moves their values into a new Dict. Adding all entries at once
382 // results in a faster initial sort operation. Takes move iterators to avoid
383 // having to clone the input.
384 template <class IteratorType>
385 explicit Dict(std::move_iterator<IteratorType> first,
386 std::move_iterator<IteratorType> last) {
387 // Need to move into a vector first, since `storage_` currently uses
389 std::vector<std::pair<std::string, std::unique_ptr<Value>>> values;
390 for (auto current = first; current != last; ++current) {
391 // With move iterators, no need to call Clone(), but do need to move
392 // to a temporary first, as accessing either field individually will
393 // directly from the iterator will delete the other field.
394 auto value = *current;
395 values.emplace_back(std::move(value.first),
396 std::make_unique<Value>(std::move(value.second)));
399 flat_map<std::string, std::unique_ptr<Value>>(std::move(values));
404 // TODO(dcheng): Probably need to allow construction from a pair of
405 // iterators for now due to the prevalence of DictStorage.
407 // Returns true if there are no entries in this dictionary and false
411 // Returns the number of entries in this dictionary.
414 // Returns an iterator to the first entry in this dictionary.
416 const_iterator begin() const;
417 const_iterator cbegin() const;
419 // Returns an iterator following the last entry in this dictionary. May not
422 const_iterator end() const;
423 const_iterator cend() const;
425 // Returns true if `key` is an entry in this dictionary.
426 bool contains(base::StringPiece key) const;
428 // Removes all entries from this dictionary.
431 // Removes the entry referenced by `pos` in this dictionary and returns an
432 // iterator to the entry following the removed entry.
433 iterator erase(iterator pos);
434 iterator erase(const_iterator pos);
436 // Creates a deep copy of this dictionary.
439 // Merges the entries from `dict` into this dictionary. If an entry with the
440 // same key exists in this dictionary and `dict`:
441 // - if both entries are dictionaries, they will be recursively merged
442 // - otherwise, the already-existing entry in this dictionary will be
443 // overwritten with the entry from `dict`.
444 void Merge(Dict dict);
446 // Finds the entry corresponding to `key` in this dictionary. Returns
447 // nullptr if there is no such entry.
448 const Value* Find(StringPiece key) const;
449 Value* Find(StringPiece key);
451 // Similar to `Find()` above, but returns `absl::nullopt`/`nullptr` if the
452 // type of the entry does not match. `bool`, `int`, and `double` are
453 // returned in a wrapped `absl::optional`; blobs, `Value::Dict`, and
454 // `Value::List` are returned by pointer.
455 absl::optional<bool> FindBool(StringPiece key) const;
456 absl::optional<int> FindInt(StringPiece key) const;
457 // Returns a non-null value for both `Value::Type::DOUBLE` and
458 // `Value::Type::INT`, converting the latter to a double.
459 absl::optional<double> FindDouble(StringPiece key) const;
460 const std::string* FindString(StringPiece key) const;
461 std::string* FindString(StringPiece key);
462 const BlobStorage* FindBlob(StringPiece key) const;
463 const Dict* FindDict(StringPiece key) const;
464 Dict* FindDict(StringPiece key);
465 const List* FindList(StringPiece key) const;
466 List* FindList(StringPiece key);
468 // If there's a value of the specified type at `key` in this dictionary,
469 // returns it. Otherwise, creates an empty container of the specified type,
470 // inserts it at `key`, and returns it. If there's a value of some other
471 // type at `key`, will overwrite that entry.
472 Dict* EnsureDict(StringPiece key);
473 List* EnsureList(StringPiece key);
475 // Sets an entry with `key` and `value` in this dictionary, overwriting any
476 // existing entry with the same `key`. Returns a pointer to the set `value`.
477 Value* Set(StringPiece key, Value&& value);
478 Value* Set(StringPiece key, bool value);
479 template <typename T>
480 Value* Set(StringPiece, const T*) = delete;
481 Value* Set(StringPiece key, int value);
482 Value* Set(StringPiece key, double value);
483 Value* Set(StringPiece key, StringPiece value);
484 Value* Set(StringPiece key, StringPiece16 value);
485 Value* Set(StringPiece key, const char* value);
486 Value* Set(StringPiece key, const char16_t* value);
487 Value* Set(StringPiece key, std::string&& value);
488 Value* Set(StringPiece key, BlobStorage&& value);
489 Value* Set(StringPiece key, Dict&& value);
490 Value* Set(StringPiece key, List&& value);
492 // Removes the entry corresponding to `key` from this dictionary. Returns
493 // true if an entry was removed or false otherwise.
494 bool Remove(StringPiece key);
496 // Similar to `Remove()`, but returns the value corresponding to the removed
497 // entry or `absl::nullopt` otherwise.
498 absl::optional<Value> Extract(StringPiece key);
500 // Equivalent to the above methods but operating on paths instead of keys.
501 // A path is shorthand syntax for referring to a key nested inside
502 // intermediate dictionaries, with components delimited by ".". Paths may
505 // Prefer the non-path methods above when possible. Paths that have only one
506 // component (i.e. no dots in the path) should never use the path-based
509 // Originally, the path-based APIs were the only way of specifying a key, so
510 // there are likely to be many legacy (and unnecessary) uses of the path
511 // APIs that do not actually require traversing nested dictionaries.
512 const Value* FindByDottedPath(StringPiece path) const;
513 Value* FindByDottedPath(StringPiece path);
515 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
516 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
517 // Returns a non-null value for both `Value::Type::DOUBLE` and
518 // `Value::Type::INT`, converting the latter to a double.
519 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
520 const std::string* FindStringByDottedPath(StringPiece path) const;
521 std::string* FindStringByDottedPath(StringPiece path);
522 const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
523 const Dict* FindDictByDottedPath(StringPiece path) const;
524 Dict* FindDictByDottedPath(StringPiece path);
525 const List* FindListByDottedPath(StringPiece path) const;
526 List* FindListByDottedPath(StringPiece path);
528 // Creates a new entry with a dictionary for any non-last component that is
529 // missing an entry while performing the path traversal. Will fail if any
530 // non-last component of the path refers to an already-existing entry that
531 // is not a dictionary. Returns `nullptr` on failure.
532 Value* SetByDottedPath(StringPiece path, Value&& value);
533 Value* SetByDottedPath(StringPiece path, bool value);
534 template <typename T>
535 Value* SetByDottedPath(StringPiece, const T*) = delete;
536 Value* SetByDottedPath(StringPiece path, int value);
537 Value* SetByDottedPath(StringPiece path, double value);
538 Value* SetByDottedPath(StringPiece path, StringPiece value);
539 Value* SetByDottedPath(StringPiece path, StringPiece16 value);
540 Value* SetByDottedPath(StringPiece path, const char* value);
541 Value* SetByDottedPath(StringPiece path, const char16_t* value);
542 Value* SetByDottedPath(StringPiece path, std::string&& value);
543 Value* SetByDottedPath(StringPiece path, BlobStorage&& value);
544 Value* SetByDottedPath(StringPiece path, Dict&& value);
545 Value* SetByDottedPath(StringPiece path, List&& value);
547 bool RemoveByDottedPath(StringPiece path);
549 absl::optional<Value> ExtractByDottedPath(StringPiece path);
551 // Serializes to a string for logging and debug purposes.
552 std::string DebugString() const;
554 #if BUILDFLAG(ENABLE_BASE_TRACING)
555 // Write this object into a trace.
556 void WriteIntoTrace(perfetto::TracedValue) const;
557 #endif // BUILDFLAG(ENABLE_BASE_TRACING)
560 BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs);
561 BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs);
562 BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs);
563 BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
564 BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
565 BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);
567 // For legacy access to the internal storage type.
570 explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);
572 flat_map<std::string, std::unique_ptr<Value>> storage_;
575 // Represents a list of Values.
576 class BASE_EXPORT GSL_OWNER List {
578 using iterator = CheckedContiguousIterator<Value>;
579 using const_iterator = CheckedContiguousConstIterator<Value>;
580 using value_type = Value;
584 List(List&&) noexcept;
585 List& operator=(List&&) noexcept;
587 // Deleted to prevent accidental copying.
588 List(const List&) = delete;
589 List& operator=(const List&) = delete;
593 // TODO(dcheng): Probably need to allow construction from a pair of
594 // iterators for now due to the prevalence of ListStorage now.
596 // Returns true if there are no values in this list and false otherwise.
599 // Returns the number of values in this list.
602 // Returns an iterator to the first value in this list.
604 const_iterator begin() const;
605 const_iterator cbegin() const;
607 // Returns an iterator following the last value in this list. May not be
610 const_iterator end() const;
611 const_iterator cend() const;
613 // Returns a reference to the first value in the container. Fails with
614 // `CHECK()` if the list is empty.
615 const Value& front() const;
618 // Returns a reference to the last value in the container. Fails with
619 // `CHECK()` if the list is empty.
620 const Value& back() const;
623 // Increase the capacity of the backing container, but does not change
624 // the size. Assume all existing iterators will be invalidated.
625 void reserve(size_t capacity);
627 // Returns a reference to the value at `index` in this list. Fails with a
628 // `CHECK()` if `index >= size()`.
629 const Value& operator[](size_t index) const;
630 Value& operator[](size_t index);
632 // Removes all value from this list.
635 // Removes the value referenced by `pos` in this list and returns an
636 // iterator to the value following the removed value.
637 iterator erase(iterator pos);
638 const_iterator erase(const_iterator pos);
640 // Remove the values in the range [`first`, `last`). Returns iterator to the
641 // first value following the removed range, which is `last`. If `first` ==
642 // `last`, removes nothing and returns `last`.
643 iterator erase(iterator first, iterator last);
644 const_iterator erase(const_iterator first, const_iterator last);
646 // Creates a deep copy of this dictionary.
649 // Appends `value` to the end of this list.
650 void Append(Value&& value);
651 void Append(bool value);
652 template <typename T>
653 void Append(const T*) = delete;
654 void Append(int value);
655 void Append(double value);
656 void Append(StringPiece value);
657 void Append(StringPiece16 value);
658 void Append(const char* value);
659 void Append(const char16_t* value);
660 void Append(std::string&& value);
661 void Append(BlobStorage&& value);
662 void Append(Dict&& value);
663 void Append(List&& value);
665 // Inserts `value` before `pos` in this list. Returns an iterator to the
667 // TODO(dcheng): Should this provide the same set of overloads that Append()
669 iterator Insert(const_iterator pos, Value&& value);
671 // Erases all values equal to `value` from this list.
672 size_t EraseValue(const Value& value);
674 // Erases all values for which `predicate` evaluates to true from this list.
675 template <typename Predicate>
676 size_t EraseIf(Predicate predicate) {
677 return base::EraseIf(storage_, predicate);
680 // Serializes to a string for logging and debug purposes.
681 std::string DebugString() const;
683 #if BUILDFLAG(ENABLE_BASE_TRACING)
684 // Write this object into a trace.
685 void WriteIntoTrace(perfetto::TracedValue) const;
686 #endif // BUILDFLAG(ENABLE_BASE_TRACING)
689 BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
690 BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
691 BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
692 BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
693 BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
694 BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);
696 // For legacy access to the internal storage type.
699 explicit List(const std::vector<Value>& storage);
701 std::vector<Value> storage_;
704 // ===== DEPRECATED methods that require `type() == Type::LIST` =====
706 // Returns the Values in a list as a view. The mutable overload allows for
707 // modification of the underlying values, but does not allow changing the
708 // structure of the list.
710 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
711 // `GetList()` otherwise.
712 DeprecatedListView GetListDeprecated();
713 DeprecatedConstListView GetListDeprecated() const;
715 // Appends `value` to the end of the list.
717 // DEPRECATED: prefer `Value::List::Append()`.
718 void Append(Value&& value);
719 // DEPRECATED: prefer `Value::List::Append()`.
720 void Append(bool value);
721 template <typename T>
722 void Append(const T* ptr) = delete;
723 // DEPRECATED: prefer `Value::List::Append()`.
724 void Append(int value);
725 // DEPRECATED: prefer `Value::List::Append()`.
726 void Append(double value);
727 // DEPRECATED: prefer `Value::List::Append()`.
728 void Append(StringPiece value);
729 // DEPRECATED: prefer `Value::List::Append()`.
730 void Append(StringPiece16 value);
731 // DEPRECATED: prefer `Value::List::Append()`.
732 void Append(const char* value);
733 // DEPRECATED: prefer `Value::List::Append()`.
734 void Append(std::string&& value);
736 // Erases all Values from the list.
738 // DEPRECATED: prefer `Value::List::clear()`.
741 // ===== DEPRECATED methods that require `type() == Type::DICT` =====
743 // `FindKey` looks up `key` in the underlying dictionary. If found, it returns
744 // a pointer to the element. Otherwise it returns nullptr.
746 // DEPRECATED: prefer `Value::Dict::Find()`.
747 Value* FindKey(StringPiece key);
748 const Value* FindKey(StringPiece key) const;
750 // `FindKeyOfType` is similar to `FindKey`, but it also requires the found
751 // value to have type `type`. If no type is found, or the found value is of a
752 // different type nullptr is returned.
754 // DEPRECATED: prefer `Value::Dict::FindBool()`, `Value::Dict::FindInt()`, et
756 Value* FindKeyOfType(StringPiece key, Type type);
757 const Value* FindKeyOfType(StringPiece key, Type type) const;
759 // These are convenience forms of `FindKey`. They return `absl::nullopt` or
760 // `nullptr` if the value is not found or doesn't have the type specified in
761 // the function's name.
763 // DEPRECATED: prefer `Value::Dict::FindBool()`.
764 absl::optional<bool> FindBoolKey(StringPiece key) const;
765 // DEPRECATED: prefer `Value::Dict::FindInt()`.
766 absl::optional<int> FindIntKey(StringPiece key) const;
767 // Returns a non-null value for both `Value::Type::DOUBLE` and
768 // `Value::Type::INT`, converting the latter to a double.
770 // DEPRECATED: prefer `Value::Dict::FindDouble()`.
771 absl::optional<double> FindDoubleKey(StringPiece key) const;
772 // DEPRECATED: prefer `Value::Dict::FindString()`.
773 const std::string* FindStringKey(StringPiece key) const;
774 std::string* FindStringKey(StringPiece key);
775 // DEPRECATED: prefer `Value::Dict::FindBlob()`.
776 const BlobStorage* FindBlobKey(StringPiece key) const;
777 // DEPRECATED: prefer `Value::Dict::FindDict()`.
778 const Value* FindDictKey(StringPiece key) const;
779 Value* FindDictKey(StringPiece key);
780 // DEPRECATED: prefer `Value::Dict::FindList()`.
781 const Value* FindListKey(StringPiece key) const;
782 Value* FindListKey(StringPiece key);
784 // `SetKey` looks up `key` in the underlying dictionary and sets the mapped
785 // value to `value`. If `key` could not be found, a new element is inserted.
786 // A pointer to the modified item is returned.
788 // Note: Prefer `Set<Type>Key()` if the input is not already a `Value`.
790 // DEPRECATED: Prefer `Value::Dict::Set()`.
791 Value* SetKey(StringPiece key, Value&& value);
793 // `Set`Type>Key` looks up `key` in the underlying dictionary and associates a
794 // corresponding Value() constructed from the second parameter. Compared to
795 // `SetKey()`, this avoids un-necessary temporary `Value()` creation, as well
796 // ambiguities in the value type.
798 // DEPRECATED: Prefer `Value::Dict::Set()`.
799 Value* SetBoolKey(StringPiece key, bool val);
800 // DEPRECATED: Prefer `Value::Dict::Set()`.
801 Value* SetIntKey(StringPiece key, int val);
802 // DEPRECATED: Prefer `Value::Dict::Set()`.
803 Value* SetDoubleKey(StringPiece key, double val);
804 // DEPRECATED: Prefer `Value::Dict::Set()`.
805 Value* SetStringKey(StringPiece key, StringPiece val);
806 // DEPRECATED: Prefer `Value::Dict::Set()`.
807 Value* SetStringKey(StringPiece key, StringPiece16 val);
808 // DEPRECATED: Prefer `Value::Dict::Set()`.
809 Value* SetStringKey(StringPiece key, const char* val);
810 // DEPRECATED: Prefer `Value::Dict::Set()`.
811 Value* SetStringKey(StringPiece key, std::string&& val);
813 // This attempts to remove the value associated with `key`. In case of
814 // failure, e.g. the key does not exist, false is returned and the underlying
815 // dictionary is not changed. In case of success, `key` is deleted from the
816 // dictionary and the method returns true.
818 // Deprecated: Prefer `Value::Dict::Remove()`.
819 bool RemoveKey(StringPiece key);
821 // This attempts to extract the value associated with `key`. In case of
822 // failure, e.g. the key does not exist, nullopt is returned and the
823 // underlying dictionary is not changed. In case of success, `key` is deleted
824 // from the dictionary and the method returns the extracted Value.
826 // DEPRECATED: Prefer `Value::Dict::Extract()`.
827 absl::optional<Value> ExtractKey(StringPiece key);
829 // Searches a hierarchy of dictionary values for a given value. If a path
830 // of dictionaries exist, returns the item at that path. If any of the path
831 // components do not exist or if any but the last path components are not
832 // dictionaries, returns nullptr. The type of the leaf Value is not checked.
834 // This version takes a StringPiece for the path, using dots as separators.
836 // DEPRECATED: Prefer `Value::Dict::FindByDottedPath()`.
837 Value* FindPath(StringPiece path);
838 const Value* FindPath(StringPiece path) const;
840 // There are also deprecated versions that take the path parameter
841 // as either a std::initializer_list<StringPiece> or a
842 // span<const StringPiece>. The latter is useful to use a
843 // std::vector<std::string> as a parameter but creates huge dynamic
844 // allocations and should be avoided!
845 // Note: If there is only one component in the path, use `FindKey()` instead.
848 // std::vector<StringPiece> components = ...
849 // auto* found = FindPath(components);
851 // DEPRECATED: These are not common, and there is no currently planned
853 Value* FindPath(std::initializer_list<StringPiece> path);
854 Value* FindPath(span<const StringPiece> path);
855 const Value* FindPath(std::initializer_list<StringPiece> path) const;
856 const Value* FindPath(span<const StringPiece> path) const;
858 // Like FindPath() but will only return the value if the leaf Value type
859 // matches the given type. Will return nullptr otherwise.
860 // Note: Prefer `Find<Type>Path()` for simple values.
862 // Note: If there is only one component in the path, use `FindKeyOfType()`
863 // instead for slightly better performance.
865 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`,
866 // `Value::Dict::FindIntByDottedPath()`, et cetera.
867 const Value* FindPathOfType(StringPiece path, Type type) const;
869 // Convenience accessors used when the expected type of a value is known.
870 // Similar to Find<Type>Key() but accepts paths instead of keys.
872 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`, or
873 // `Value::Dict::FindBool()` if the path only has one component, i.e. has no
875 absl::optional<bool> FindBoolPath(StringPiece path) const;
876 // DEPRECATED: Use `Value::Dict::FindIntByDottedPath()`, or
877 // `Value::Dict::FindInt()` if the path only has one component, i.e. has no
879 absl::optional<int> FindIntPath(StringPiece path) const;
880 // DEPRECATED: Use `Value::Dict::FindDoubleByDottedPath()`, or
881 // `Value::Dict::FindDouble()` if the path only has one component, i.e. has no
883 absl::optional<double> FindDoublePath(StringPiece path) const;
884 // DEPRECATED: Use `Value::Dict::FindStringByDottedPath()`, or
885 // `Value::Dict::FindString()` if the path only has one component, i.e. has no
887 const std::string* FindStringPath(StringPiece path) const;
888 std::string* FindStringPath(StringPiece path);
889 // DEPRECATED: Use `Value::Dict::FindDictByDottedPath()`, or
890 // `Value::Dict::FindDict()` if the path only has one component, i.e. has no
892 Value* FindDictPath(StringPiece path);
893 const Value* FindDictPath(StringPiece path) const;
894 // DEPRECATED: Use `Value::Dict::FindListByDottedPath()`, or
895 // `Value::Dict::FindList()` if the path only has one component, i.e. has no
897 Value* FindListPath(StringPiece path);
898 const Value* FindListPath(StringPiece path) const;
900 // The following forms are deprecated too, use the ones that take the path
901 // as a single StringPiece instead.
903 // DEPRECATED: These are not common, and there is no currently planned
905 Value* FindPathOfType(std::initializer_list<StringPiece> path, Type type);
906 Value* FindPathOfType(span<const StringPiece> path, Type type);
907 const Value* FindPathOfType(std::initializer_list<StringPiece> path,
909 const Value* FindPathOfType(span<const StringPiece> path, Type type) const;
911 // Sets the given path, expanding and creating dictionary keys as necessary.
913 // If the current value is not a dictionary, the function returns nullptr. If
914 // path components do not exist, they will be created. If any but the last
915 // components matches a value that is not a dictionary, the function will fail
916 // (it will not overwrite the value) and return nullptr. The last path
917 // component will be unconditionally overwritten if it exists, and created if
920 // Note: If there is only one component in the path, use `SetKey()` instead.
921 // Note: Using `Set<Type>Path()` might be more convenient and efficient.
923 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
924 Value* SetPath(StringPiece path, Value&& value);
926 // These setters are more convenient and efficient than the corresponding
927 // SetPath(...) call.
929 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
930 Value* SetBoolPath(StringPiece path, bool value);
931 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
932 Value* SetIntPath(StringPiece path, int value);
933 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
934 Value* SetDoublePath(StringPiece path, double value);
935 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
936 Value* SetStringPath(StringPiece path, StringPiece value);
937 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
938 Value* SetStringPath(StringPiece path, const char* value);
939 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
940 Value* SetStringPath(StringPiece path, std::string&& value);
941 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
942 Value* SetStringPath(StringPiece path, StringPiece16 value);
944 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
945 Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
946 Value* SetPath(span<const StringPiece> path, Value&& value);
948 // Tries to remove a Value at the given path.
950 // If the current value is not a dictionary or any path component does not
951 // exist, this operation fails, leaves underlying Values untouched and returns
952 // `false`. In case intermediate dictionaries become empty as a result of this
953 // path removal, they will be removed as well.
954 // Note: If there is only one component in the path, use `RemoveKey()`
957 // DEPRECATED: Use `Value::Dict::RemoveByDottedPath()`.
958 bool RemovePath(StringPiece path);
960 using dict_iterator_proxy = detail::dict_iterator_proxy;
961 using const_dict_iterator_proxy = detail::const_dict_iterator_proxy;
963 // `DictItems` returns a proxy object that exposes iterators to the underlying
964 // dictionary. These are intended for iteration over all items in the
965 // dictionary and are compatible with for-each loops and standard library
968 // Unlike with std::map, a range-for over the non-const version of
969 // `DictItems()` will range over items of type
970 // `pair<const std::string&, Value&>`, so code of the form
971 // for (auto kv : my_value.DictItems())
972 // Mutate(kv.second);
973 // will actually alter `my_value` in place (if it isn't const).
975 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
977 dict_iterator_proxy DictItems();
978 const_dict_iterator_proxy DictItems() const;
980 // DEPRECATED: prefer `Value::Dict::size()`.
981 size_t DictSize() const;
983 // DEPRECATED: prefer `Value::Dict::empty()`.
984 bool DictEmpty() const;
986 // DEPRECATED: prefer `Value::Dict::clear()`.
989 // Merge `dictionary` into this value. This is done recursively, i.e. any
990 // sub-dictionaries will be merged as well. In case of key collisions, the
991 // passed in dictionary takes precedence and data already present will be
992 // replaced. Values within `dictionary` are deep-copied, so `dictionary` may
993 // be freed any time after this call.
994 // Note: This requires that `type()` and `dictionary->type()` is
997 // DEPRECATED: prefer `Value::Dict::Merge()`.
998 void MergeDictionary(const Value* dictionary);
1000 // These methods allow the convenient retrieval of the contents of the Value.
1001 // If the current object can be converted into the given type, the value is
1002 // returned through the `out_value` parameter and true is returned;
1003 // otherwise, false is returned and `out_value` is unchanged.
1004 // DictionaryValue::From is the equivalent for std::unique_ptr conversions.
1006 // DEPRECATED: prefer direct use `base::Value::Dict` where possible, or
1007 // `GetIfDict()` otherwise.
1008 bool GetAsDictionary(DictionaryValue** out_value);
1009 bool GetAsDictionary(const DictionaryValue** out_value) const;
1010 // Note: Do not add more types. See the file-level comment above for why.
1012 // This creates a deep copy of the entire Value tree, and returns a pointer
1013 // to the copy. The caller gets ownership of the copy, of course.
1014 // Subclasses return their own type directly in their overrides;
1015 // this works because C++ supports covariant return types.
1016 // TODO(crbug.com/646113): Delete this and migrate callsites.
1018 // DEPRECATED: prefer `Value::Clone()`.
1019 std::unique_ptr<Value> CreateDeepCopy() const;
1021 // Comparison operators so that Values can easily be used with standard
1022 // library algorithms and associative containers.
1023 BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
1024 BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs);
1025 BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs);
1026 BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs);
1027 BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
1028 BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);
1030 BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs);
1031 friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; }
1032 friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); }
1033 friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); }
1034 template <typename T>
1035 friend bool operator==(const Value& lhs, const T* rhs) = delete;
1036 template <typename T>
1037 friend bool operator==(const T* lhs, const Value& rhs) = delete;
1038 template <typename T>
1039 friend bool operator!=(const Value& lhs, const T* rhs) = delete;
1040 template <typename T>
1041 friend bool operator!=(const T* lhs, const Value& rhs) = delete;
1042 BASE_EXPORT friend bool operator==(const Value& lhs, int rhs);
1043 friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; }
1044 friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); }
1045 friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); }
1046 BASE_EXPORT friend bool operator==(const Value& lhs, double rhs);
1047 friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; }
1048 friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); }
1049 friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); }
1050 // Note: StringPiece16 overload intentionally omitted: Value internally stores
1051 // strings as UTF-8. While it is possible to implement a comparison operator
1052 // that would not require first creating a new UTF-8 string from the UTF-16
1053 // string argument, it is simpler to just not implement it at all for a rare
1055 BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs);
1056 friend bool operator==(StringPiece lhs, const Value& rhs) {
1059 friend bool operator!=(const Value& lhs, StringPiece rhs) {
1060 return !(lhs == rhs);
1062 friend bool operator!=(StringPiece lhs, const Value& rhs) {
1063 return !(lhs == rhs);
1065 friend bool operator==(const Value& lhs, const char* rhs) {
1066 return lhs == StringPiece(rhs);
1068 friend bool operator==(const char* lhs, const Value& rhs) {
1071 friend bool operator!=(const Value& lhs, const char* rhs) {
1072 return !(lhs == rhs);
1074 friend bool operator!=(const char* lhs, const Value& rhs) {
1075 return !(lhs == rhs);
1077 friend bool operator==(const Value& lhs, const std::string& rhs) {
1078 return lhs == StringPiece(rhs);
1080 friend bool operator==(const std::string& lhs, const Value& rhs) {
1083 friend bool operator!=(const Value& lhs, const std::string& rhs) {
1084 return !(lhs == rhs);
1086 friend bool operator!=(const std::string& lhs, const Value& rhs) {
1087 return !(lhs == rhs);
1089 // Note: Blob support intentionally omitted as an experiment for potentially
1090 // wholly removing Blob support from Value itself in the future.
1091 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs);
1092 friend bool operator==(const Value::Dict& lhs, const Value& rhs) {
1095 friend bool operator!=(const Value& lhs, const Value::Dict& rhs) {
1096 return !(lhs == rhs);
1098 friend bool operator!=(const Value::Dict& lhs, const Value& rhs) {
1099 return !(lhs == rhs);
1101 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs);
1102 friend bool operator==(const Value::List& lhs, const Value& rhs) {
1105 friend bool operator!=(const Value& lhs, const Value::List& rhs) {
1106 return !(lhs == rhs);
1108 friend bool operator!=(const Value::List& lhs, const Value& rhs) {
1109 return !(lhs == rhs);
1112 // Estimates dynamic memory usage. Requires tracing support
1113 // (enable_base_tracing gn flag), otherwise always returns 0. See
1114 // base/trace_event/memory_usage_estimator.h for more info.
1115 size_t EstimateMemoryUsage() const;
1117 // Serializes to a string for logging and debug purposes.
1118 std::string DebugString() const;
1120 #if BUILDFLAG(ENABLE_BASE_TRACING)
1121 // Write this object into a trace.
1122 void WriteIntoTrace(perfetto::TracedValue) const;
1123 #endif // BUILDFLAG(ENABLE_BASE_TRACING)
1125 template <typename Visitor>
1126 auto Visit(Visitor&& visitor) const {
1127 return absl::visit(std::forward<Visitor>(visitor), data_);
1131 // TODO(https://crbug.com/1187091): Once deprecated list methods and ListView
1132 // have been removed, make this a private member of List.
1133 using ListStorage = DeprecatedListStorage;
1135 // Checked convenience accessors for dict and list.
1136 const LegacyDictStorage& dict() const { return GetDict().storage_; }
1137 LegacyDictStorage& dict() { return GetDict().storage_; }
1138 const ListStorage& list() const { return GetList().storage_; }
1139 ListStorage& list() { return GetList().storage_; }
1141 // Internal constructors, allowing the simplify the implementation of Clone().
1142 explicit Value(const LegacyDictStorage& storage);
1143 explicit Value(LegacyDictStorage&& storage) noexcept;
1146 // For access to DoubleStorage.
1147 friend class ValueView;
1149 // Special case for doubles, which are aligned to 8 bytes on some
1150 // 32-bit architectures. In this case, a simple declaration as a
1151 // double member would make the whole union 8 byte-aligned, which
1152 // would also force 4 bytes of wasted padding space before it in
1153 // the Value layout.
1155 // To override this, store the value as an array of 32-bit integers, and
1156 // perform the appropriate bit casts when reading / writing to it.
1157 class BASE_EXPORT DoubleStorage {
1159 explicit DoubleStorage(double v);
1160 DoubleStorage(const DoubleStorage&) = default;
1161 DoubleStorage& operator=(const DoubleStorage&) = default;
1163 // Provide an implicit conversion to double to simplify the use of visitors
1164 // with `Value::Visit()`. Otherwise, visitors would need a branch for
1165 // handling `DoubleStorage` like:
1167 // value.Visit([] (const auto& member) {
1168 // using T = std::decay_t<decltype(member)>;
1169 // if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
1170 // SomeFunction(double{member});
1172 // SomeFunction(member);
1175 operator double() const { return base::bit_cast<double>(v_); }
1178 friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1179 return double{lhs} == double{rhs};
1182 friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1183 return !(lhs == rhs);
1186 friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1187 return double{lhs} < double{rhs};
1190 friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1194 friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1195 return !(rhs < lhs);
1198 friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1199 return !(lhs < rhs);
1202 alignas(4) std::array<char, sizeof(double)> v_;
1205 // Internal constructors, allowing the simplify the implementation of Clone().
1206 explicit Value(absl::monostate);
1207 explicit Value(DoubleStorage storage);
1209 // A helper for static functions used for cloning a Value or a ValueView.
1210 class CloningHelper;
1212 absl::variant<absl::monostate,
1223 // DictAdapterForMigration is an adapter class to help the migration of
1224 // base::DictionaryValue to base::Value::Dict.
1226 // DictAdapterForMigration mirrors the API of base::Value::Dict,
1227 // and is implicitly constructable from both base::DictionaryValue
1228 // and base::Value::Dict. Currently this is read-only, similar to StringPiece.
1230 // To migrate a function that takes a base::DictionaryValue, change the
1231 // signature to take DictAdapterForMigration instead, and update the
1232 // function body to use the Dict::Value API.
1233 // The call sites can be left unchanged and migrated later.
1235 // Note that DictAdapterForMigration is intended as a shim to help migrations,
1236 // and will go away with base::DictionaryValue.
1237 class BASE_EXPORT GSL_POINTER DictAdapterForMigration {
1239 using iterator = detail::dict_iterator;
1240 using const_iterator = detail::const_dict_iterator;
1242 DictAdapterForMigration() = delete;
1244 // NOLINTNEXTLINE(google-explicit-constructor)
1245 DictAdapterForMigration(const Value::Dict&) noexcept;
1246 // NOLINTNEXTLINE(google-explicit-constructor)
1247 DictAdapterForMigration(const DictionaryValue&) noexcept;
1250 size_t size() const;
1252 const_iterator begin() const;
1253 const_iterator cbegin() const;
1254 const_iterator end() const;
1255 const_iterator cend() const;
1257 bool contains(base::StringPiece key) const;
1259 Value::Dict Clone() const;
1261 const Value* Find(StringPiece key) const;
1262 absl::optional<bool> FindBool(StringPiece key) const;
1263 absl::optional<int> FindInt(StringPiece key) const;
1264 absl::optional<double> FindDouble(StringPiece key) const;
1265 const std::string* FindString(StringPiece key) const;
1266 const Value::BlobStorage* FindBlob(StringPiece key) const;
1267 const Value::Dict* FindDict(StringPiece key) const;
1268 const Value::List* FindList(StringPiece key) const;
1270 const Value* FindByDottedPath(StringPiece path) const;
1272 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
1273 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
1274 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
1275 const std::string* FindStringByDottedPath(StringPiece path) const;
1276 const Value::BlobStorage* FindBlobByDottedPath(StringPiece path) const;
1277 const Value::Dict* FindDictByDottedPath(StringPiece path) const;
1278 const Value::List* FindListByDottedPath(StringPiece path) const;
1280 std::string DebugString() const;
1282 #if BUILDFLAG(ENABLE_BASE_TRACING)
1283 void WriteIntoTrace(perfetto::TracedValue) const;
1284 #endif // BUILDFLAG(ENABLE_BASE_TRACING)
1286 const Value::Dict& dict_for_test() const;
1289 const Value::Dict& dict_;
1292 // DictionaryValue provides a key-value dictionary with (optional) "path"
1293 // parsing for recursive access; see the comment at the top of the file. Keys
1294 // are std::string's and should be UTF-8 encoded.
1296 // DEPRECATED: prefer `Value::Dict`.
1297 class BASE_EXPORT DictionaryValue : public Value {
1299 // Returns `value` if it is a dictionary, nullptr otherwise.
1300 static std::unique_ptr<DictionaryValue> From(std::unique_ptr<Value> value);
1303 explicit DictionaryValue(const LegacyDictStorage& in_dict);
1304 explicit DictionaryValue(LegacyDictStorage&& in_dict) noexcept;
1306 // Sets the Value associated with the given path starting from this object.
1307 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1308 // into the next DictionaryValue down. Obviously, "." can't be used
1309 // within a key, but there are no other restrictions on keys.
1310 // If the key at any step of the way doesn't exist, or exists but isn't
1311 // a DictionaryValue, a new DictionaryValue will be created and attached
1312 // to the path in that location. `in_value` must be non-null.
1313 // Returns a pointer to the inserted value.
1315 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1316 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1318 Value* Set(StringPiece path, std::unique_ptr<Value> in_value);
1320 // Convenience forms of Set(). These methods will replace any existing
1321 // value at that path, even if it has a different type.
1323 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1324 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1326 Value* SetBoolean(StringPiece path, bool in_value);
1327 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1328 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1330 Value* SetInteger(StringPiece path, int in_value);
1331 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1332 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1334 Value* SetString(StringPiece path, StringPiece in_value);
1335 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1336 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1338 Value* SetString(StringPiece path, const std::u16string& in_value);
1339 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1340 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1342 ListValue* SetList(StringPiece path, std::unique_ptr<ListValue> in_value);
1344 // Gets the Value associated with the given path starting from this object.
1345 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1346 // into the next DictionaryValue down. If the path can be resolved
1347 // successfully, the value for the last key in the path will be returned
1348 // through the `out_value` parameter, and the function will return true.
1349 // Otherwise, it will return false and `out_value` will be untouched.
1350 // Note that the dictionary always owns the value that's returned.
1351 // `out_value` is optional and will only be set if non-NULL.
1353 // DEPRECATED: prefer `Value::Dict::Find()` (if the path only has one
1354 // component, i.e. has no dots), or `Value::Dict::FindByDottedPath()`
1356 bool Get(StringPiece path, const Value** out_value) const;
1357 bool Get(StringPiece path, Value** out_value);
1359 // These are convenience forms of `Get()`. The value will be retrieved
1360 // and the return value will be true if the path is valid and the value at
1361 // the end of the path can be returned in the form specified.
1362 // `out_value` is optional and will only be set if non-NULL.
1364 // DEPRECATED: prefer `Value::Dict::FindInt()` (if the path only has one
1365 // component, i.e. has no dots), or `Value::Dict::FindIntByDottedPath()`
1367 bool GetInteger(StringPiece path, int* out_value) const;
1368 // DEPRECATED: prefer `Value::Dict::FindString()` (if the path only has one
1369 // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
1371 bool GetString(StringPiece path, std::string* out_value) const;
1372 // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
1373 // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
1375 bool GetDictionary(StringPiece path, const DictionaryValue** out_value) const;
1376 bool GetDictionary(StringPiece path, DictionaryValue** out_value);
1377 // DEPRECATED: prefer `Value::Dict::FindList()` (if the path only has one
1378 // component, i.e. has no dots), or `Value::Dict::FindListByDottedPath()`
1380 bool GetList(StringPiece path, const ListValue** out_value) const;
1381 bool GetList(StringPiece path, ListValue** out_value);
1383 // Swaps contents with the `other` dictionary.
1384 void Swap(DictionaryValue* other);
1386 // DEPRECATED, use `Value::Dict::Clone()` instead.
1387 // TODO(crbug.com/646113): Delete this and migrate callsites.
1388 std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
1391 // This type of Value represents a list of other Value values.
1393 // DEPRECATED: prefer `base::Value::List`.
1394 class BASE_EXPORT ListValue : public Value {
1396 using const_iterator = ListView::const_iterator;
1397 using iterator = ListView::iterator;
1399 // Returns `value` if it is a list, nullptr otherwise.
1400 static std::unique_ptr<ListValue> From(std::unique_ptr<Value> value);
1404 // Appends a Value to the end of the list.
1405 // DEPRECATED: prefer `Value::List::Append()`.
1406 using Value::Append;
1407 // DEPRECATED: prefer `Value::List::Append()`. Provided to simplify
1408 // incremental migration and intentionally only defined on ListValue and not
1410 void Append(base::Value::Dict in_dict);
1411 void Append(base::Value::List in_list);
1413 // Iteration: Use a range-based for loop over `base::Value::List` directly
1417 // Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
1418 // serialization methods without having to clone the contents and transfer
1419 // ownership of the clone to a `Value` wrapper object.
1421 // Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
1422 // underlying object that is passed by reference (i.e. `std::string`,
1423 // `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
1424 // live as long as there is a `ValueView` referencing it.
1426 // While it might be nice to just use the `absl::variant` type directly, the
1427 // need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
1428 // `std::reference_wrapper` both support implicit construction, but C++ only
1429 // allows at most one user-defined conversion in an implicit conversion
1430 // sequence. If this adapter and its implicit constructors did not exist,
1431 // callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
1432 // `Value::List` to a function with a `ValueView` parameter.
1433 class BASE_EXPORT GSL_POINTER ValueView {
1435 ValueView() = default;
1436 ValueView(bool value) : data_view_(value) {}
1437 template <typename T>
1438 ValueView(const T*) = delete;
1439 ValueView(int value) : data_view_(value) {}
1440 ValueView(double value)
1441 : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
1442 ValueView(StringPiece value) : data_view_(value) {}
1443 ValueView(const char* value) : ValueView(StringPiece(value)) {}
1444 ValueView(const std::string& value) : ValueView(StringPiece(value)) {}
1445 // Note: UTF-16 is intentionally not supported. ValueView is intended to be a
1446 // low-cost view abstraction, but Value internally represents strings as
1447 // UTF-8, so it would not be possible to implement this without allocating an
1448 // entirely new UTF-8 string.
1449 ValueView(const Value::BlobStorage& value) : data_view_(value) {}
1450 ValueView(const Value::Dict& value) : data_view_(value) {}
1451 ValueView(const Value::List& value) : data_view_(value) {}
1452 ValueView(const Value& value);
1454 // This is the only 'getter' method provided as `ValueView` is not intended
1455 // to be a general replacement of `Value`.
1456 template <typename Visitor>
1457 auto Visit(Visitor&& visitor) const {
1458 return absl::visit(std::forward<Visitor>(visitor), data_view_);
1461 // Returns a clone of the underlying Value.
1462 Value ToValue() const;
1466 absl::variant<absl::monostate,
1469 Value::DoubleStorage,
1471 std::reference_wrapper<const Value::BlobStorage>,
1472 std::reference_wrapper<const Value::Dict>,
1473 std::reference_wrapper<const Value::List>>;
1476 using DoubleStorageForTest = Value::DoubleStorage;
1477 const ViewType& data_view_for_test() const { return data_view_; }
1480 ViewType data_view_;
1483 // This interface is implemented by classes that know how to serialize
1485 class BASE_EXPORT ValueSerializer {
1487 virtual ~ValueSerializer();
1489 virtual bool Serialize(ValueView root) = 0;
1492 // This interface is implemented by classes that know how to deserialize Value
1494 class BASE_EXPORT ValueDeserializer {
1496 virtual ~ValueDeserializer();
1498 // This method deserializes the subclass-specific format into a Value object.
1499 // If the return value is non-NULL, the caller takes ownership of returned
1502 // If the return value is nullptr, and if `error_code` is non-nullptr,
1503 // `*error_code` will be set to an integer value representing the underlying
1504 // error. See "enum ErrorCode" below for more detail about the integer value.
1506 // If `error_message` is non-nullptr, it will be filled in with a formatted
1507 // error message including the location of the error if appropriate.
1508 virtual std::unique_ptr<Value> Deserialize(int* error_code,
1509 std::string* error_message) = 0;
1511 // The integer-valued error codes form four groups:
1512 // - The value 0 means no error.
1513 // - Values between 1 and 999 inclusive mean an error in the data (i.e.
1514 // content). The bytes being deserialized are not in the right format.
1515 // - Values 1000 and above mean an error in the metadata (i.e. context). The
1516 // file could not be read, the network is down, etc.
1517 // - Negative values are reserved.
1519 // These values are persisted to logs. Entries should not be renumbered and
1520 // numeric values should never be reused.
1522 kErrorCodeNoError = 0,
1523 // kErrorCodeInvalidFormat is a generic error code for "the data is not in
1524 // the right format". Subclasses of ValueDeserializer may return other
1525 // values for more specific errors.
1526 kErrorCodeInvalidFormat = 1,
1527 // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
1528 // range of metadata errors.
1529 kErrorCodeFirstMetadataError = 1000,
1532 // The `error_code` argument can be one of the ErrorCode values, but it is
1533 // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
1534 // can define their own error code values.
1535 static inline bool ErrorCodeIsDataError(int error_code) {
1536 return (kErrorCodeInvalidFormat <= error_code) &&
1537 (error_code < kErrorCodeFirstMetadataError);
1541 // Stream operator so Values can be pretty printed by gtest.
1542 BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
1543 BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1544 const Value::Dict& dict);
1545 BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1546 const Value::List& list);
1548 // Hints for DictionaryValue and ListValue; otherwise, gtest tends to prefer the
1549 // default template implementation over an upcast to Value.
1550 BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
1551 const DictionaryValue& value) {
1552 return out << static_cast<const Value&>(value);
1555 BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
1556 const ListValue& value) {
1557 return out << static_cast<const Value&>(value);
1560 // Stream operator so that enum class Types can be used in log statements.
1561 BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1562 const Value::Type& type);
1566 #endif // BASE_VALUES_H_