blob: 7ade51423ca3ed3b10ec8a3b2f96d81d0d94fe52 [file] [log] [blame]
[email protected]13502562012-05-09 21:54:271// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]101d5422008-09-26 20:22:425#ifndef BASE_VALUES_H_
6#define BASE_VALUES_H_
initial.commitd7cae122008-07-26 21:49:387
[email protected]c014f2b32013-09-03 23:29:128#include <stddef.h>
avi9b6f42932015-12-26 22:15:149#include <stdint.h>
[email protected]c014f2b32013-09-03 23:29:1210
Daniel Cheng782d2ba32022-02-16 19:40:2911#include <array>
Lei Zhang935738a2021-05-17 21:35:5312#include <initializer_list>
[email protected]c014f2b32013-09-03 23:29:1213#include <iosfwd>
Matt Menkee311c6d2022-06-14 20:17:3914#include <iterator>
dcheng093de9b2016-04-04 21:25:5115#include <memory>
[email protected]8e50b602009-03-03 22:59:4316#include <string>
[email protected]c014f2b32013-09-03 23:29:1217#include <utility>
initial.commitd7cae122008-07-26 21:49:3818#include <vector>
19
[email protected]0bea7252011-08-05 15:34:0020#include "base/base_export.h"
Daniel Cheng782d2ba32022-02-16 19:40:2921#include "base/bit_cast.h"
Daniel Cheng8ac305b2022-02-17 00:05:1122#include "base/compiler_specific.h"
Jan Wilken Dörrie7e7a9792019-10-15 14:42:0523#include "base/containers/checked_iterators.h"
Jan Wilken Dörrie8d9034f12019-11-28 14:48:5724#include "base/containers/checked_range.h"
Lei Zhanga1209af2021-06-26 03:26:2425#include "base/containers/cxx20_erase_vector.h"
mkwstcd8067b2017-04-11 06:52:2126#include "base/containers/flat_map.h"
jdoerriecd022242017-08-23 08:38:2727#include "base/containers/span.h"
asvitkinedbd26533e2015-06-23 18:22:5228#include "base/strings/string_piece.h"
Alexander Timine68aeb32021-04-11 23:06:2129#include "base/trace_event/base_tracing_forward.h"
jdoerrie44efa9d2017-07-14 14:47:2030#include "base/value_iterators.h"
Anton Bikineev7dd58ad2021-05-18 01:01:3931#include "third_party/abseil-cpp/absl/types/optional.h"
Jan Wilken Dörrie79d022142020-08-19 18:18:3232#include "third_party/abseil-cpp/absl/types/variant.h"
initial.commitd7cae122008-07-26 21:49:3833
[email protected]f3a1c642011-07-12 19:15:0334namespace base {
35
initial.commitd7cae122008-07-26 21:49:3836class DictionaryValue;
37class ListValue;
38
Daniel Chenga367fe52022-02-15 18:08:4839// The `Value` class is a variant type can hold one of the following types:
40// - null
41// - bool
42// - int
43// - double
44// - string (internally UTF8-encoded)
45// - binary data (i.e. a blob)
46// - dictionary of string keys to `Value`s
47// - list of `Value`s
[email protected]2f03f532013-07-17 08:43:3348//
Daniel Chenga367fe52022-02-15 18:08:4849// With the exception of binary blobs, `Value` is intended to be the C++ version
50// of data types that can be represented in JSON.
Brett Wilson4bef8ee2017-09-01 20:11:4951//
Daniel Chenga367fe52022-02-15 18:08:4852// Warning: blob support may be removed in the future.
53//
54// ## Usage
55//
56// Do not use `Value` if a more specific type would be more appropriate. For
57// example, a function that only accepts dictionary values should have a
58// `base::Value::Dict` parameter, not a `base::Value` parameter.
59//
60// Construction:
61//
62// `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
63// (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
64// `Value::Dict`, and `Value::List`.
65//
66// Copying:
67//
68// `Value` does not support C++ copy semantics to make it harder to accidentally
69// copy large values. Instead, use `Clone()` to manually create a deep copy.
70//
71// Reading:
72//
73// `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
74// subtype before returning the contained value. `bool`, `int`, `double` are
75// returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
76// are returned by reference.
77//
78// `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
79// the `Value` does not have the correct subtype; otherwise, returns the value
80// wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
81// (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
82//
83// Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
84// when the subtype is `Value::Type::INT`. In that case, the stored value is
85// coerced to a double before being returned.
86//
87// Assignment:
88//
89// It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
90// Instead, wrap the underlying type in `Value` before assigning.
91//
92// ## Dictionaries and Lists
93//
94// `Value` provides the `Value::Dict` and `Value::List` container types for
95// working with dictionaries and lists of values respectively, rather than
96// exposing the underlying container types directly. This allows the types to
97// provide convenient helpers for dictionaries and lists, as well as giving
98// greater flexibility for changing implementation details in the future.
99//
100// Both container types support enough STL-isms to be usable in range-based for
101// loops and generic operations such as those from <algorithm>.
102//
103// Dictionaries support:
104// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
105// `contains()`, `clear()`, `erase()`: Identical to the STL container
106// equivalents, with additional safety checks, e.g. iterators will
107// `CHECK()` if `end()` is dereferenced.
108//
109// - `Clone()`: Create a deep copy.
110// - `Merge()`: Merge another dictionary into this dictionary.
111// - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
112// is not present.
113// - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
114// `Value` also has the correct subtype. Same return semantics as
115// `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
116// `nullptr` if the key is not present or the value has the wrong subtype.
117// - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
118// of the subtypes that `Value` can hold.
119// - `Remove()`: Remove the key from this dictionary, if present.
120// - `Extract()`: If the key is present in the dictionary, removes the key from
121// the dictionary and transfers ownership of `Value` to the caller.
122// Otherwise, returns `absl::nullopt`.
123//
124// Dictionaries also support an additional set of helper methods that operate on
125// "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
126// and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
127// intermediate nested dictionaries, separating the components of the path using
128// '.' characters. For example, finding a string path on a `Value::Dict` using
129// the dotted path:
130//
131// "aaa.bbb.ccc"
132//
133// Will first look for a `Value::Type::DICT` associated with the key "aaa", then
134// another `Value::Type::DICT` under the "aaa" dict associated with the
135// key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
136// with the key "ccc".
137//
Daniel Cheng619653b2022-02-17 18:33:12138// If a path only has one component (i.e. has no dots), please use the regular,
139// non-path APIs.
140//
Daniel Chenga367fe52022-02-15 18:08:48141// Lists support:
142// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
Daniel Chengc9ab0ef2022-02-18 02:34:07143// `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`:
144// Identical to the STL container equivalents, with additional safety
145// checks, e.g. `operator[]` will `CHECK()` if the index is out of range.
Daniel Chenga367fe52022-02-15 18:08:48146// - `Clone()`: Create a deep copy.
147// - `Append()`: Append a value to the end of the list. Accepts `Value` or any
148// of the subtypes that `Value` can hold.
149// - `Insert()`: Insert a `Value` at a specified point in the list.
150// - `EraseValue()`: Erases all matching `Value`s from the list.
151// - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
152// list.
153//
154// ## Refactoring Notes
155//
156// `Value` was originally implemented as a class hierarchy, with a `Value` base
157// class, and a leaf class for each of the different types of `Value` subtypes.
Brett Wilson4bef8ee2017-09-01 20:11:49158// https://docs.google.com/document/d/1uDLu5uTRlCWePxQUEHc8yNQdEoE1BDISYdpggWEABnw
Daniel Chenga367fe52022-02-15 18:08:48159// proposed an overhaul of the `Value` API that has now largely been
160// implemented, though there remains a significant amount of legacy code that is
161// still being migrated as part of the code health migration.
Brett Wilson4bef8ee2017-09-01 20:11:49162//
163// OLD WAY:
164//
165// std::unique_ptr<base::Value> GetFoo() {
166// std::unique_ptr<DictionaryValue> dict;
Daniel Chenga367fe52022-02-15 18:08:48167// dict->SetString("mykey", "foo");
Brett Wilson4bef8ee2017-09-01 20:11:49168// return dict;
169// }
170//
Brett Wilson4bef8ee2017-09-01 20:11:49171// NEW WAY:
172//
173// base::Value GetFoo() {
Daniel Chenga367fe52022-02-15 18:08:48174// base::Value::Dict dict;
Scott Haseley5fd36262022-03-04 19:35:11175// dict.Set("mykey", "abc");
Daniel Chenga367fe52022-02-15 18:08:48176// return base::Value(std::move(dict));
Brett Wilson4bef8ee2017-09-01 20:11:49177// }
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04178//
Daniel Chenga367fe52022-02-15 18:08:48179// To avoid losing type information with the new variant-based design, migration
180// off the deprecated types should use more specific subtypes where possible:
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04181//
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49182// OLD WAY:
183//
184// void AlwaysTakesList(std::unique_ptr<base::ListValue> list);
185// void AlwaysTakesDict(std::unique_ptr<base::DictionaryValue> dict);
186//
Daniel Chenga367fe52022-02-15 18:08:48187// DEPRECATED (PREVIOUS) WAY:
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49188//
189// void AlwaysTakesList(std::vector<base::Value> list);
Daniel Chenga367fe52022-02-15 18:08:48190// void AlwaysTakesListAlternative1(base::Value::ConstListView list);
191// void AlwaysTakesListAlternative2(base::Value::ListView& list);
192// void AlwaysTakesListAlterantive3(base::Value::ListStorage);
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49193// void AlwaysTakesDict(base::flat_map<std::string, base::Value> dict);
Daniel Chenga367fe52022-02-15 18:08:48194// void AlwaysTakesDictAlternative(base::Value::DictStorage);
Daniel Cheng60e6b2d2022-02-05 01:08:46195//
196// NEW WAY:
197//
Daniel Chenga367fe52022-02-15 18:08:48198// void AlwaysTakesList(base::Value::List list);
199// void AlwaysTakesDict(base::Value::Dict dict);
Daniel Cheng60e6b2d2022-02-05 01:08:46200//
Daniel Chenga367fe52022-02-15 18:08:48201// Migrating code may require conversions on API boundaries. If something seems
202// awkward/inefficient, please reach out to #code-health-rotation on Slack for
203// consultation: it is entirely possible that certain classes of APIs may be
204// missing due to an unrealized need.
Daniel Cheng8ac305b2022-02-17 00:05:11205class BASE_EXPORT GSL_OWNER Value {
initial.commitd7cae122008-07-26 21:49:38206 public:
jdoerrie9970f20e2018-07-20 21:41:18207 using BlobStorage = std::vector<uint8_t>;
Daniel Cheng773ce4502022-01-28 15:25:06208
209 using DeprecatedListStorage = std::vector<Value>;
Matt Menke167ca682022-06-08 23:19:28210 // TODO(https://crbug.com/1291666): Make this private.
Daniel Cheng773ce4502022-01-28 15:25:06211 using ListStorage = DeprecatedListStorage;
Jan Wilken Dörrief961a372020-11-02 20:30:34212
213 // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is
Matt Menkee311c6d2022-06-14 20:17:39214 // due to legacy reasons, and should be replaced with
215 // flat_map<std::string, Value> once no caller relies on stability of pointers
Matt Menke167ca682022-06-08 23:19:28216 // anymore.
Jan Wilken Dörrief961a372020-11-02 20:30:34217 using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57218
Daniel Cheng773ce4502022-01-28 15:25:06219 using DeprecatedListView = CheckedContiguousRange<ListStorage>;
220 using DeprecatedConstListView = CheckedContiguousConstRange<ListStorage>;
221 // TODO(https://crbug.com/1291666): Make these private.
222 using ListView = DeprecatedListView;
223 using ConstListView = DeprecatedConstListView;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57224
Daniel Chenga367fe52022-02-15 18:08:48225 class Dict;
226 class List;
227
Jose Dapena Paz7685422a2019-04-03 18:35:04228 enum class Type : unsigned char {
jdoerriedc72ee942016-12-07 15:43:28229 NONE = 0,
230 BOOLEAN,
231 INTEGER,
232 DOUBLE,
233 STRING,
234 BINARY,
Daniel Chenga367fe52022-02-15 18:08:48235 DICT,
236 // TODO(https://crbug.com/1291670): Deprecated and will be removed.
237 DICTIONARY = DICT,
jdoerriee1b1f3a2019-03-16 04:08:01238 LIST,
[email protected]2f03f532013-07-17 08:43:33239 // Note: Do not add more types. See the file-level comment above for why.
[email protected]a502bbe72011-01-07 18:06:45240 };
241
Lei Zhang30895d52017-10-23 19:14:46242 // 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);
Lei Zhang8c1432b2019-10-08 18:48:54245 static const DictionaryValue& AsDictionaryValue(const Value& val);
246 static const ListValue& AsListValue(const Value& val);
Lei Zhang30895d52017-10-23 19:14:46247
Jan Wilken Dörrie79d022142020-08-19 18:18:32248 Value() noexcept;
jdoerriecc9f5732017-08-23 14:12:30249
Daniel Chenga367fe52022-02-15 18:08:48250 Value(Value&&) noexcept;
251 Value& operator=(Value&&) noexcept;
jdoerriecc9f5732017-08-23 14:12:30252
Daniel Chenga367fe52022-02-15 18:08:48253 // Deleted to prevent accidental copying.
David Bienvenu5f4d4f02020-09-27 16:55:03254 Value(const Value&) = delete;
255 Value& operator=(const Value&) = delete;
jdoerrie05eb3162017-02-01 10:36:56256
Daniel Chenga367fe52022-02-15 18:08:48257 // Creates a deep copy of this value.
258 Value Clone() const;
259
260 // Creates a `Value` of `type`. The data of the corresponding type will be
261 // default constructed.
262 explicit Value(Type type);
263
264 // Constructor for `Value::Type::BOOLEAN`.
265 explicit Value(bool value);
266
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).
272 //
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;
277
278 // Constructor for `Value::Type::INT`.
279 explicit Value(int value);
280
281 // Constructor for `Value::Type::DOUBLE`.
282 explicit Value(double value);
283
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;
293
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;
298
299 // Constructor for `Value::Type::DICT`.
300 explicit Value(Dict&& value) noexcept;
301
302 // Constructor for `Value::Type::LIST`.
303 explicit Value(List&& value) noexcept;
304
Daniel Cheng619653b2022-02-17 18:33:12305 // DEPRECATED: prefer `Value(List&&)`.
Daniel Chenga367fe52022-02-15 18:08:48306 explicit Value(span<const Value> value);
307 explicit Value(ListStorage&& value) noexcept;
308
jdoerrie8e945542017-02-17 13:54:49309 ~Value();
jdoerrie05eb3162017-02-01 10:36:56310
Gabriel Charetteb49d73a2021-05-05 20:05:59311 // Returns the name for a given `type`.
thestig61709242016-07-19 00:39:30312 static const char* GetTypeName(Type type);
313
initial.commitd7cae122008-07-26 21:49:38314 // Returns the type of the value stored by the current Value object.
Jan Wilken Dörrie79d022142020-08-19 18:18:32315 Type type() const { return static_cast<Type>(data_.index()); }
initial.commitd7cae122008-07-26 21:49:38316
317 // Returns true if the current object represents a given type.
jdoerriecc9f5732017-08-23 14:12:30318 bool is_none() const { return type() == Type::NONE; }
jdoerrie05eb3162017-02-01 10:36:56319 bool is_bool() const { return type() == Type::BOOLEAN; }
320 bool is_int() const { return type() == Type::INTEGER; }
321 bool is_double() const { return type() == Type::DOUBLE; }
322 bool is_string() const { return type() == Type::STRING; }
323 bool is_blob() const { return type() == Type::BINARY; }
Daniel Chenga367fe52022-02-15 18:08:48324 bool is_dict() const { return type() == Type::DICT; }
jdoerrie05eb3162017-02-01 10:36:56325 bool is_list() const { return type() == Type::LIST; }
326
Daniel Chenga367fe52022-02-15 18:08:48327 // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
328 // otherwise. `bool`, `int`, and `double` are returned in a wrapped
329 // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
330 // pointer.
Anton Bikineev7dd58ad2021-05-18 01:01:39331 absl::optional<bool> GetIfBool() const;
332 absl::optional<int> GetIfInt() const;
Daniel Chenga367fe52022-02-15 18:08:48333 // Returns a non-null value for both `Value::Type::DOUBLE` and
334 // `Value::Type::INT`, converting the latter to a double.
Anton Bikineev7dd58ad2021-05-18 01:01:39335 absl::optional<double> GetIfDouble() const;
Jan Wilken Dörrie2e125622021-02-17 10:52:53336 const std::string* GetIfString() const;
Daniel Chenga367fe52022-02-15 18:08:48337 std::string* GetIfString();
Jan Wilken Dörrie2e125622021-02-17 10:52:53338 const BlobStorage* GetIfBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48339 const Dict* GetIfDict() const;
340 Dict* GetIfDict();
341 const List* GetIfList() const;
342 List* GetIfList();
Jan Wilken Dörrie2e125622021-02-17 10:52:53343
Daniel Chenga367fe52022-02-15 18:08:48344 // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
345 // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
346 // `Value::Dict`, and `Value::List` are returned by reference.
jdoerrie05eb3162017-02-01 10:36:56347 bool GetBool() const;
348 int GetInt() const;
Daniel Chenga367fe52022-02-15 18:08:48349 // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
350 // converting the latter to a double.
351 double GetDouble() const;
Daniel Cheng1cdf99782022-06-29 19:25:58352 // Callers that want to transfer ownership can use std::move() in conjunction
353 // with one of the mutable variants below, e.g.:
354 // std::string taken_string = std::move(value.GetString());
355 // base::Value::Dict taken_dict = std::move(value.GetDict());
356 // base::Value::List taken_list = std::move(value.GetList());
jdoerrief38f37b2017-02-01 14:38:32357 const std::string& GetString() const;
Dominic Battre08cbe972019-07-31 03:57:19358 std::string& GetString();
jdoerrie5f12b6272017-04-18 10:22:41359 const BlobStorage& GetBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48360 const Dict& GetDict() const;
361 Dict& GetDict();
362 const List& GetList() const;
363 List& GetList();
364
365 // Represents a dictionary of string keys to Values.
Daniel Cheng8ac305b2022-02-17 00:05:11366 class BASE_EXPORT GSL_OWNER Dict {
Daniel Chenga367fe52022-02-15 18:08:48367 public:
368 using iterator = detail::dict_iterator;
369 using const_iterator = detail::const_dict_iterator;
370
371 Dict();
372
373 Dict(Dict&&) noexcept;
374 Dict& operator=(Dict&&) noexcept;
375
376 // Deleted to prevent accidental copying.
377 Dict(const Dict&) = delete;
378 Dict& operator=(const Dict&) = delete;
379
Matt Menkee311c6d2022-06-14 20:17:39380 // 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
388 // unique_ptrs.
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)));
397 }
398 storage_ =
399 flat_map<std::string, std::unique_ptr<Value>>(std::move(values));
400 }
401
Daniel Chenga367fe52022-02-15 18:08:48402 ~Dict();
403
404 // TODO(dcheng): Probably need to allow construction from a pair of
405 // iterators for now due to the prevalence of DictStorage.
406
407 // Returns true if there are no entries in this dictionary and false
408 // otherwise.
409 bool empty() const;
410
411 // Returns the number of entries in this dictionary.
412 size_t size() const;
413
414 // Returns an iterator to the first entry in this dictionary.
415 iterator begin();
416 const_iterator begin() const;
417 const_iterator cbegin() const;
418
419 // Returns an iterator following the last entry in this dictionary. May not
420 // be dereferenced.
421 iterator end();
422 const_iterator end() const;
423 const_iterator cend() const;
424
425 // Returns true if `key` is an entry in this dictionary.
426 bool contains(base::StringPiece key) const;
427
428 // Removes all entries from this dictionary.
429 void clear();
430
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);
435
436 // Creates a deep copy of this dictionary.
437 Dict Clone() const;
438
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`.
Daniel Cheng1cdf99782022-06-29 19:25:58444 void Merge(Dict dict);
Daniel Chenga367fe52022-02-15 18:08:48445
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);
450
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);
467
468 // Sets an entry with `key` and `value` in this dictionary, overwriting any
469 // existing entry with the same `key`. Returns a pointer to the set `value`.
470 Value* Set(StringPiece key, Value&& value);
471 Value* Set(StringPiece key, bool value);
472 template <typename T>
473 Value* Set(StringPiece, const T*) = delete;
474 Value* Set(StringPiece key, int value);
475 Value* Set(StringPiece key, double value);
476 Value* Set(StringPiece key, StringPiece value);
477 Value* Set(StringPiece key, StringPiece16 value);
478 Value* Set(StringPiece key, const char* value);
479 Value* Set(StringPiece key, const char16_t* value);
480 Value* Set(StringPiece key, std::string&& value);
481 Value* Set(StringPiece key, BlobStorage&& value);
482 Value* Set(StringPiece key, Dict&& value);
483 Value* Set(StringPiece key, List&& value);
484
485 // Removes the entry corresponding to `key` from this dictionary. Returns
486 // true if an entry was removed or false otherwise.
487 bool Remove(StringPiece key);
488
489 // Similar to `Remove()`, but returns the value corresponding to the removed
490 // entry or `absl::nullopt` otherwise.
491 absl::optional<Value> Extract(StringPiece key);
492
493 // Equivalent to the above methods but operating on paths instead of keys.
494 // A path is shorthand syntax for referring to a key nested inside
495 // intermediate dictionaries, with components delimited by ".". Paths may
496 // not be empty.
497 //
Daniel Cheng619653b2022-02-17 18:33:12498 // Prefer the non-path methods above when possible. Paths that have only one
499 // component (i.e. no dots in the path) should never use the path-based
500 // methods.
501 //
502 // Originally, the path-based APIs were the only way of specifying a key, so
503 // there are likely to be many legacy (and unnecessary) uses of the path
504 // APIs that do not actually require traversing nested dictionaries.
Daniel Chenga367fe52022-02-15 18:08:48505 const Value* FindByDottedPath(StringPiece path) const;
506 Value* FindByDottedPath(StringPiece path);
507
508 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
509 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
510 // Returns a non-null value for both `Value::Type::DOUBLE` and
511 // `Value::Type::INT`, converting the latter to a double.
512 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
513 const std::string* FindStringByDottedPath(StringPiece path) const;
514 std::string* FindStringByDottedPath(StringPiece path);
515 const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
516 const Dict* FindDictByDottedPath(StringPiece path) const;
517 Dict* FindDictByDottedPath(StringPiece path);
518 const List* FindListByDottedPath(StringPiece path) const;
519 List* FindListByDottedPath(StringPiece path);
520
Daniel Cheng619653b2022-02-17 18:33:12521 // Creates a new entry with a dictionary for any non-last component that is
522 // missing an entry while performing the path traversal. Will fail if any
523 // non-last component of the path refers to an already-existing entry that
524 // is not a dictionary. Returns `nullptr` on failure.
Daniel Chenga367fe52022-02-15 18:08:48525 Value* SetByDottedPath(StringPiece path, Value&& value);
526 Value* SetByDottedPath(StringPiece path, bool value);
527 template <typename T>
528 Value* SetByDottedPath(StringPiece, const T*) = delete;
529 Value* SetByDottedPath(StringPiece path, int value);
530 Value* SetByDottedPath(StringPiece path, double value);
531 Value* SetByDottedPath(StringPiece path, StringPiece value);
532 Value* SetByDottedPath(StringPiece path, StringPiece16 value);
533 Value* SetByDottedPath(StringPiece path, const char* value);
534 Value* SetByDottedPath(StringPiece path, const char16_t* value);
535 Value* SetByDottedPath(StringPiece path, std::string&& value);
536 Value* SetByDottedPath(StringPiece path, BlobStorage&& value);
537 Value* SetByDottedPath(StringPiece path, Dict&& value);
538 Value* SetByDottedPath(StringPiece path, List&& value);
539
540 bool RemoveByDottedPath(StringPiece path);
541
542 absl::optional<Value> ExtractByDottedPath(StringPiece path);
543
Scott Haseleye51040782022-03-09 17:32:37544 // Serializes to a string for logging and debug purposes.
545 std::string DebugString() const;
546
Daniel Chengb5862bc2022-06-09 17:04:06547#if BUILDFLAG(ENABLE_BASE_TRACING)
548 // Write this object into a trace.
549 void WriteIntoTrace(perfetto::TracedValue) const;
550#endif // BUILDFLAG(ENABLE_BASE_TRACING)
551
Daniel Chenga367fe52022-02-15 18:08:48552 private:
553 BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs);
554 BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs);
555 BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs);
556 BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
557 BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
558 BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);
559
560 // For legacy access to the internal storage type.
561 friend Value;
562
563 explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);
564
565 flat_map<std::string, std::unique_ptr<Value>> storage_;
566 };
567
568 // Represents a list of Values.
Daniel Cheng8ac305b2022-02-17 00:05:11569 class BASE_EXPORT GSL_OWNER List {
Daniel Chenga367fe52022-02-15 18:08:48570 public:
571 using iterator = CheckedContiguousIterator<Value>;
572 using const_iterator = CheckedContiguousConstIterator<Value>;
573
574 List();
575
576 List(List&&) noexcept;
577 List& operator=(List&&) noexcept;
578
579 // Deleted to prevent accidental copying.
580 List(const List&) = delete;
581 List& operator=(const List&) = delete;
582
583 ~List();
584
585 // TODO(dcheng): Probably need to allow construction from a pair of
586 // iterators for now due to the prevalence of ListStorage now.
587
588 // Returns true if there are no values in this list and false otherwise.
589 bool empty() const;
590
591 // Returns the number of values in this list.
592 size_t size() const;
593
594 // Returns an iterator to the first value in this list.
595 iterator begin();
596 const_iterator begin() const;
597 const_iterator cbegin() const;
598
599 // Returns an iterator following the last value in this list. May not be
600 // dereferenced.
601 iterator end();
602 const_iterator end() const;
603 const_iterator cend() const;
604
Daniel Chengc9ab0ef2022-02-18 02:34:07605 // Returns a reference to the first value in the container. Fails with
606 // `CHECK()` if the list is empty.
607 const Value& front() const;
608 Value& front();
609
610 // Returns a reference to the last value in the container. Fails with
611 // `CHECK()` if the list is empty.
612 const Value& back() const;
613 Value& back();
614
615 // Increase the capacity of the backing container, but does not change
616 // the size. Assume all existing iterators will be invalidated.
617 void reserve(size_t capacity);
618
Daniel Chenga367fe52022-02-15 18:08:48619 // Returns a reference to the value at `index` in this list. Fails with a
620 // `CHECK()` if `index >= size()`.
621 const Value& operator[](size_t index) const;
622 Value& operator[](size_t index);
623
624 // Removes all value from this list.
625 void clear();
626
Daniel Chengc9ab0ef2022-02-18 02:34:07627 // Removes the value referenced by `pos` in this list and returns an
628 // iterator to the value following the removed value.
Daniel Chenga367fe52022-02-15 18:08:48629 iterator erase(iterator pos);
630 const_iterator erase(const_iterator pos);
631
632 // Creates a deep copy of this dictionary.
633 List Clone() const;
634
635 // Appends `value` to the end of this list.
636 void Append(Value&& value);
637 void Append(bool value);
638 template <typename T>
639 void Append(const T*) = delete;
640 void Append(int value);
641 void Append(double value);
642 void Append(StringPiece value);
643 void Append(StringPiece16 value);
644 void Append(const char* value);
645 void Append(const char16_t* value);
646 void Append(std::string&& value);
647 void Append(BlobStorage&& value);
648 void Append(Dict&& value);
649 void Append(List&& value);
650
651 // Inserts `value` before `pos` in this list. Returns an iterator to the
652 // inserted value.
653 // TODO(dcheng): Should this provide the same set of overloads that Append()
654 // does?
655 iterator Insert(const_iterator pos, Value&& value);
656
657 // Erases all values equal to `value` from this list.
658 size_t EraseValue(const Value& value);
659
660 // Erases all values for which `predicate` evaluates to true from this list.
661 template <typename Predicate>
662 size_t EraseIf(Predicate predicate) {
663 return base::EraseIf(storage_, predicate);
664 }
665
Scott Haseleye51040782022-03-09 17:32:37666 // Serializes to a string for logging and debug purposes.
667 std::string DebugString() const;
668
Daniel Chengb5862bc2022-06-09 17:04:06669#if BUILDFLAG(ENABLE_BASE_TRACING)
670 // Write this object into a trace.
671 void WriteIntoTrace(perfetto::TracedValue) const;
672#endif // BUILDFLAG(ENABLE_BASE_TRACING)
673
Daniel Chenga367fe52022-02-15 18:08:48674 private:
675 BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
676 BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
677 BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
678 BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
679 BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
680 BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);
681
682 // For legacy access to the internal storage type.
683 friend Value;
684
685 explicit List(const std::vector<Value>& storage);
686
687 std::vector<Value> storage_;
688 };
jdoerriee03e80f2017-02-15 08:42:14689
Daniel Cheng619653b2022-02-17 18:33:12690 // ===== DEPRECATED methods that require `type() == Type::LIST` =====
691
Jan Wilken Dörrie69a65a3a2020-01-16 15:03:30692 // Returns the Values in a list as a view. The mutable overload allows for
693 // modification of the underlying values, but does not allow changing the
Daniel Cheng60e6b2d2022-02-05 01:08:46694 // structure of the list. If this is desired, use `TakeListDeprecated()`,
695 // perform the operations, and return the list back to the Value via move
696 // assignment.
Daniel Cheng619653b2022-02-17 18:33:12697 //
698 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
699 // `GetList()` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06700 DeprecatedListView GetListDeprecated();
701 DeprecatedConstListView GetListDeprecated() const;
jdoerrie2b7d0fcd2017-04-19 07:15:38702
Lei Zhang20b21af82020-08-10 18:31:58703 // Transfers ownership of the underlying list to the caller. Subsequent
Daniel Cheng60e6b2d2022-02-05 01:08:46704 // calls to `GetListDeprecated()` will return an empty list.
Daniel Cheng619653b2022-02-17 18:33:12705 //
706 // DEPRECATED: prefer direct use of `base::Value::List` where possible, or
707 // `std::move(value.GetList())` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06708 DeprecatedListStorage TakeListDeprecated() &&;
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05709
Gabriel Charetteb49d73a2021-05-05 20:05:59710 // Appends `value` to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:12711 //
712 // DEPRECATED: prefer `Value::List::Append()`.
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24713 void Append(Value&& value);
Daniel Cheng619653b2022-02-17 18:33:12714 // DEPRECATED: prefer `Value::List::Append()`.
715 void Append(bool value);
716 template <typename T>
717 void Append(const T* ptr) = delete;
718 // DEPRECATED: prefer `Value::List::Append()`.
719 void Append(int value);
720 // DEPRECATED: prefer `Value::List::Append()`.
721 void Append(double value);
722 // DEPRECATED: prefer `Value::List::Append()`.
723 void Append(StringPiece value);
724 // DEPRECATED: prefer `Value::List::Append()`.
725 void Append(StringPiece16 value);
726 // DEPRECATED: prefer `Value::List::Append()`.
727 void Append(const char* value);
728 // DEPRECATED: prefer `Value::List::Append()`.
729 void Append(const char16_t* value);
730 // DEPRECATED: prefer `Value::List::Append()`.
731 void Append(std::string&& value);
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24732
Gabriel Charetteb49d73a2021-05-05 20:05:59733 // Inserts `value` before `pos`.
Daniel Cheng619653b2022-02-17 18:33:12734 //
735 // DEPRECATED: prefer `Value::List::Insert()`.
Jan Wilken Dörrie9065545e12019-10-30 10:44:51736 CheckedContiguousIterator<Value> Insert(
737 CheckedContiguousConstIterator<Value> pos,
738 Value&& value);
739
Gabriel Charetteb49d73a2021-05-05 20:05:59740 // Erases the Value pointed to by `iter`. Returns false if `iter` is out of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05741 // bounds.
Daniel Cheng619653b2022-02-17 18:33:12742 //
743 // DEPRECATED: prefer `Value::List::erase(iter)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05744 bool EraseListIter(CheckedContiguousConstIterator<Value> iter);
745
Gabriel Charetteb49d73a2021-05-05 20:05:59746 // Erases all Values that compare equal to `val`. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05747 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12748 //
749 // DEPRECATED: prefer `Value::List::EraseValue(val)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05750 size_t EraseListValue(const Value& val);
751
Gabriel Charetteb49d73a2021-05-05 20:05:59752 // Erases all Values for which `pred` returns true. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05753 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12754 //
755 // DEPRECATED: prefer `Value::List::EraseIf(pred)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05756 template <typename Predicate>
757 size_t EraseListValueIf(Predicate pred) {
Jan Wilken Dörrie79d022142020-08-19 18:18:32758 return base::EraseIf(list(), pred);
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05759 }
760
Jan Wilken Dörrie02577a22019-12-04 14:27:39761 // Erases all Values from the list.
Daniel Cheng619653b2022-02-17 18:33:12762 //
763 // DEPRECATED: prefer `Value::List::clear()`.
Jan Wilken Dörrie02577a22019-12-04 14:27:39764 void ClearList();
765
Daniel Cheng619653b2022-02-17 18:33:12766 // ===== DEPRECATED methods that require `type() == Type::DICT` =====
767
Gabriel Charetteb49d73a2021-05-05 20:05:59768 // `FindKey` looks up `key` in the underlying dictionary. If found, it returns
jdoerrie78ab7a22017-08-17 19:04:45769 // a pointer to the element. Otherwise it returns nullptr.
jdoerrie78ab7a22017-08-17 19:04:45770 //
Daniel Cheng619653b2022-02-17 18:33:12771 // DEPRECATED: prefer `Value::Dict::Find()`.
jdoerrie78ab7a22017-08-17 19:04:45772 Value* FindKey(StringPiece key);
773 const Value* FindKey(StringPiece key) const;
jdoerrie44efa9d2017-07-14 14:47:20774
Gabriel Charetteb49d73a2021-05-05 20:05:59775 // `FindKeyOfType` is similar to `FindKey`, but it also requires the found
776 // value to have type `type`. If no type is found, or the found value is of a
jdoerrie78ab7a22017-08-17 19:04:45777 // different type nullptr is returned.
jdoerrie78ab7a22017-08-17 19:04:45778 //
Daniel Cheng619653b2022-02-17 18:33:12779 // DEPRECATED: prefer `Value::Dict::FindBool()`, `Value::Dict::FindInt()`, et
780 // cetera.
jdoerrie78ab7a22017-08-17 19:04:45781 Value* FindKeyOfType(StringPiece key, Type type);
782 const Value* FindKeyOfType(StringPiece key, Type type) const;
jdoerrie44efa9d2017-07-14 14:47:20783
Daniel Cheng619653b2022-02-17 18:33:12784 // These are convenience forms of `FindKey`. They return `absl::nullopt` or
785 // `nullptr` if the value is not found or doesn't have the type specified in
786 // the function's name.
787 //
788 // DEPRECATED: prefer `Value::Dict::FindBool()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39789 absl::optional<bool> FindBoolKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12790 // DEPRECATED: prefer `Value::Dict::FindInt()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39791 absl::optional<int> FindIntKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12792 // Returns a non-null value for both `Value::Type::DOUBLE` and
793 // `Value::Type::INT`, converting the latter to a double.
794 //
795 // DEPRECATED: prefer `Value::Dict::FindDouble()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39796 absl::optional<double> FindDoubleKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12797 // DEPRECATED: prefer `Value::Dict::FindString()`.
Vladislav Kuzkokov193a2ba2019-01-08 11:33:16798 const std::string* FindStringKey(StringPiece key) const;
Dominic Battre08cbe972019-07-31 03:57:19799 std::string* FindStringKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12800 // DEPRECATED: prefer `Value::Dict::FindBlob()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06801 const BlobStorage* FindBlobKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12802 // DEPRECATED: prefer `Value::Dict::FindDict()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06803 const Value* FindDictKey(StringPiece key) const;
804 Value* FindDictKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12805 // DEPRECATED: prefer `Value::Dict::FindList()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06806 const Value* FindListKey(StringPiece key) const;
807 Value* FindListKey(StringPiece key);
808
Gabriel Charetteb49d73a2021-05-05 20:05:59809 // `SetKey` looks up `key` in the underlying dictionary and sets the mapped
810 // value to `value`. If `key` could not be found, a new element is inserted.
jdoerrie78ab7a22017-08-17 19:04:45811 // A pointer to the modified item is returned.
jdoerrie78ab7a22017-08-17 19:04:45812 //
Daniel Cheng619653b2022-02-17 18:33:12813 // Note: Prefer `Set<Type>Key()` if the input is not already a `Value`.
814 //
815 // DEPRECATED: Prefer `Value::Dict::Set()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16816 Value* SetKey(StringPiece key, Value&& value);
jdoerrie44efa9d2017-07-14 14:47:20817
Gabriel Charetteb49d73a2021-05-05 20:05:59818 // `Set`Type>Key` looks up `key` in the underlying dictionary and associates a
819 // corresponding Value() constructed from the second parameter. Compared to
820 // `SetKey()`, this avoids un-necessary temporary `Value()` creation, as well
David 'Digit' Turnere169e6c2019-03-28 22:06:29821 // ambiguities in the value type.
Daniel Cheng619653b2022-02-17 18:33:12822 //
823 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29824 Value* SetBoolKey(StringPiece key, bool val);
Daniel Cheng619653b2022-02-17 18:33:12825 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29826 Value* SetIntKey(StringPiece key, int val);
Daniel Cheng619653b2022-02-17 18:33:12827 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29828 Value* SetDoubleKey(StringPiece key, double val);
Daniel Cheng619653b2022-02-17 18:33:12829 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29830 Value* SetStringKey(StringPiece key, StringPiece val);
Daniel Cheng619653b2022-02-17 18:33:12831 // DEPRECATED: Prefer `Value::Dict::Set()`.
Jan Wilken Dörrie293405a2020-05-12 19:45:11832 Value* SetStringKey(StringPiece key, StringPiece16 val);
Daniel Cheng619653b2022-02-17 18:33:12833 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29834 Value* SetStringKey(StringPiece key, const char* val);
Daniel Cheng619653b2022-02-17 18:33:12835 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29836 Value* SetStringKey(StringPiece key, std::string&& val);
David 'Digit' Turnere169e6c2019-03-28 22:06:29837
Gabriel Charetteb49d73a2021-05-05 20:05:59838 // This attempts to remove the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46839 // failure, e.g. the key does not exist, false is returned and the underlying
Gabriel Charetteb49d73a2021-05-05 20:05:59840 // dictionary is not changed. In case of success, `key` is deleted from the
jdoerriec209c7d2019-04-05 09:51:46841 // dictionary and the method returns true.
jdoerrie64783162017-09-04 16:33:32842 //
Daniel Cheng619653b2022-02-17 18:33:12843 // Deprecated: Prefer `Value::Dict::Remove()`.
jdoerrie64783162017-09-04 16:33:32844 bool RemoveKey(StringPiece key);
845
Gabriel Charetteb49d73a2021-05-05 20:05:59846 // This attempts to extract the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46847 // failure, e.g. the key does not exist, nullopt is returned and the
Gabriel Charetteb49d73a2021-05-05 20:05:59848 // underlying dictionary is not changed. In case of success, `key` is deleted
jdoerriec209c7d2019-04-05 09:51:46849 // from the dictionary and the method returns the extracted Value.
jdoerriec209c7d2019-04-05 09:51:46850 //
Daniel Cheng619653b2022-02-17 18:33:12851 // DEPRECATED: Prefer `Value::Dict::Extract()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39852 absl::optional<Value> ExtractKey(StringPiece key);
jdoerriec209c7d2019-04-05 09:51:46853
Brett Wilsond16cf4ee2017-08-03 00:08:27854 // Searches a hierarchy of dictionary values for a given value. If a path
855 // of dictionaries exist, returns the item at that path. If any of the path
856 // components do not exist or if any but the last path components are not
Daniel Cheng619653b2022-02-17 18:33:12857 // dictionaries, returns nullptr. The type of the leaf Value is not checked.
Brett Wilsond16cf4ee2017-08-03 00:08:27858 //
David 'Digit' Turner43ce6492019-04-04 16:04:44859 // This version takes a StringPiece for the path, using dots as separators.
Daniel Cheng619653b2022-02-17 18:33:12860 //
861 // DEPRECATED: Prefer `Value::Dict::FindByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44862 Value* FindPath(StringPiece path);
863 const Value* FindPath(StringPiece path) const;
864
865 // There are also deprecated versions that take the path parameter
866 // as either a std::initializer_list<StringPiece> or a
867 // span<const StringPiece>. The latter is useful to use a
868 // std::vector<std::string> as a parameter but creates huge dynamic
jdoerriec209c7d2019-04-05 09:51:46869 // allocations and should be avoided!
Gabriel Charetteb49d73a2021-05-05 20:05:59870 // Note: If there is only one component in the path, use `FindKey()` instead.
jdoerriec209c7d2019-04-05 09:51:46871 //
David 'Digit' Turner43ce6492019-04-04 16:04:44872 // Example:
jdoerriecd022242017-08-23 08:38:27873 // std::vector<StringPiece> components = ...
874 // auto* found = FindPath(components);
Daniel Cheng619653b2022-02-17 18:33:12875 //
876 // DEPRECATED: These are not common, and there is no currently planned
877 // replacement.
jdoerriecd022242017-08-23 08:38:27878 Value* FindPath(std::initializer_list<StringPiece> path);
879 Value* FindPath(span<const StringPiece> path);
880 const Value* FindPath(std::initializer_list<StringPiece> path) const;
881 const Value* FindPath(span<const StringPiece> path) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27882
Lei Zhange0fc6f02017-10-27 00:27:23883 // Like FindPath() but will only return the value if the leaf Value type
Brett Wilsond16cf4ee2017-08-03 00:08:27884 // matches the given type. Will return nullptr otherwise.
Gabriel Charetteb49d73a2021-05-05 20:05:59885 // Note: Prefer `Find<Type>Path()` for simple values.
Lei Zhange0fc6f02017-10-27 00:27:23886 //
Gabriel Charetteb49d73a2021-05-05 20:05:59887 // Note: If there is only one component in the path, use `FindKeyOfType()`
David 'Digit' Turner43ce6492019-04-04 16:04:44888 // instead for slightly better performance.
Daniel Cheng619653b2022-02-17 18:33:12889 //
890 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`,
891 // `Value::Dict::FindIntByDottedPath()`, et cetera.
David 'Digit' Turner43ce6492019-04-04 16:04:44892 Value* FindPathOfType(StringPiece path, Type type);
893 const Value* FindPathOfType(StringPiece path, Type type) const;
894
895 // Convenience accessors used when the expected type of a value is known.
896 // Similar to Find<Type>Key() but accepts paths instead of keys.
Daniel Cheng619653b2022-02-17 18:33:12897 //
898 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`, or
899 // `Value::Dict::FindBool()` if the path only has one component, i.e. has no
900 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39901 absl::optional<bool> FindBoolPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12902 // DEPRECATED: Use `Value::Dict::FindIntByDottedPath()`, or
903 // `Value::Dict::FindInt()` if the path only has one component, i.e. has no
904 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39905 absl::optional<int> FindIntPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12906 // DEPRECATED: Use `Value::Dict::FindDoubleByDottedPath()`, or
907 // `Value::Dict::FindDouble()` if the path only has one component, i.e. has no
908 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39909 absl::optional<double> FindDoublePath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12910 // DEPRECATED: Use `Value::Dict::FindStringByDottedPath()`, or
911 // `Value::Dict::FindString()` if the path only has one component, i.e. has no
912 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44913 const std::string* FindStringPath(StringPiece path) const;
Dominic Battre08cbe972019-07-31 03:57:19914 std::string* FindStringPath(StringPiece path);
Daniel Cheng619653b2022-02-17 18:33:12915 // DEPRECATED: Use `Value::Dict::FindBlobByDottedPath()`, or
916 // `Value::Dict::FindBlob()` if the path only has one component, i.e. has no
917 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44918 const BlobStorage* FindBlobPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12919 // DEPRECATED: Use `Value::Dict::FindDictByDottedPath()`, or
920 // `Value::Dict::FindDict()` if the path only has one component, i.e. has no
921 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44922 Value* FindDictPath(StringPiece path);
923 const Value* FindDictPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12924 // DEPRECATED: Use `Value::Dict::FindListByDottedPath()`, or
925 // `Value::Dict::FindList()` if the path only has one component, i.e. has no
926 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44927 Value* FindListPath(StringPiece path);
928 const Value* FindListPath(StringPiece path) const;
929
930 // The following forms are deprecated too, use the ones that take the path
931 // as a single StringPiece instead.
Daniel Cheng619653b2022-02-17 18:33:12932 //
933 // DEPRECATED: These are not common, and there is no currently planned
934 // replacement.
jdoerriecd022242017-08-23 08:38:27935 Value* FindPathOfType(std::initializer_list<StringPiece> path, Type type);
936 Value* FindPathOfType(span<const StringPiece> path, Type type);
937 const Value* FindPathOfType(std::initializer_list<StringPiece> path,
Brett Wilsond16cf4ee2017-08-03 00:08:27938 Type type) const;
jdoerriecd022242017-08-23 08:38:27939 const Value* FindPathOfType(span<const StringPiece> path, Type type) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27940
941 // Sets the given path, expanding and creating dictionary keys as necessary.
942 //
jdoerrie64783162017-09-04 16:33:32943 // If the current value is not a dictionary, the function returns nullptr. If
944 // path components do not exist, they will be created. If any but the last
945 // components matches a value that is not a dictionary, the function will fail
946 // (it will not overwrite the value) and return nullptr. The last path
947 // component will be unconditionally overwritten if it exists, and created if
948 // it doesn't.
Brett Wilsond16cf4ee2017-08-03 00:08:27949 //
Gabriel Charetteb49d73a2021-05-05 20:05:59950 // Note: If there is only one component in the path, use `SetKey()` instead.
951 // Note: Using `Set<Type>Path()` might be more convenient and efficient.
Daniel Cheng619653b2022-02-17 18:33:12952 //
953 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44954 Value* SetPath(StringPiece path, Value&& value);
955
956 // These setters are more convenient and efficient than the corresponding
957 // SetPath(...) call.
Daniel Cheng619653b2022-02-17 18:33:12958 //
959 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44960 Value* SetBoolPath(StringPiece path, bool value);
Daniel Cheng619653b2022-02-17 18:33:12961 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44962 Value* SetIntPath(StringPiece path, int value);
Daniel Cheng619653b2022-02-17 18:33:12963 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44964 Value* SetDoublePath(StringPiece path, double value);
Daniel Cheng619653b2022-02-17 18:33:12965 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44966 Value* SetStringPath(StringPiece path, StringPiece value);
Daniel Cheng619653b2022-02-17 18:33:12967 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44968 Value* SetStringPath(StringPiece path, const char* value);
Daniel Cheng619653b2022-02-17 18:33:12969 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44970 Value* SetStringPath(StringPiece path, std::string&& value);
Daniel Cheng619653b2022-02-17 18:33:12971 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44972 Value* SetStringPath(StringPiece path, StringPiece16 value);
973
Daniel Cheng619653b2022-02-17 18:33:12974 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16975 Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
976 Value* SetPath(span<const StringPiece> path, Value&& value);
Brett Wilsond16cf4ee2017-08-03 00:08:27977
jdoerrie64783162017-09-04 16:33:32978 // Tries to remove a Value at the given path.
979 //
jdoerriec209c7d2019-04-05 09:51:46980 // If the current value is not a dictionary or any path component does not
jdoerrie64783162017-09-04 16:33:32981 // exist, this operation fails, leaves underlying Values untouched and returns
Gabriel Charetteb49d73a2021-05-05 20:05:59982 // `false`. In case intermediate dictionaries become empty as a result of this
jdoerrie64783162017-09-04 16:33:32983 // path removal, they will be removed as well.
Song Fangzhen09e06912021-07-21 15:01:28984 // Note: If there is only one component in the path, use `RemoveKey()`
Gabriel Charetteb49d73a2021-05-05 20:05:59985 // instead.
jdoerrie64783162017-09-04 16:33:32986 //
Daniel Cheng619653b2022-02-17 18:33:12987 // DEPRECATED: Use `Value::Dict::RemoveByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44988 bool RemovePath(StringPiece path);
989
jdoerriec209c7d2019-04-05 09:51:46990 // Tries to extract a Value at the given path.
991 //
992 // If the current value is not a dictionary or any path component does not
993 // exist, this operation fails, leaves underlying Values untouched and returns
994 // nullopt. In case intermediate dictionaries become empty as a result of this
995 // path removal, they will be removed as well. Returns the extracted value on
996 // success.
Gabriel Charetteb49d73a2021-05-05 20:05:59997 // Note: If there is only one component in the path, use `ExtractKey()`
998 // instead.
jdoerriec209c7d2019-04-05 09:51:46999 //
Daniel Cheng619653b2022-02-17 18:33:121000 // DEPRECATED: Use `Value::Dict::ExtractByDottedPath()`.
Anton Bikineev7dd58ad2021-05-18 01:01:391001 absl::optional<Value> ExtractPath(StringPiece path);
jdoerriec209c7d2019-04-05 09:51:461002
jdoerrie78ab7a22017-08-17 19:04:451003 using dict_iterator_proxy = detail::dict_iterator_proxy;
1004 using const_dict_iterator_proxy = detail::const_dict_iterator_proxy;
jdoerrie44efa9d2017-07-14 14:47:201005
Gabriel Charetteb49d73a2021-05-05 20:05:591006 // `DictItems` returns a proxy object that exposes iterators to the underlying
jdoerrie44efa9d2017-07-14 14:47:201007 // dictionary. These are intended for iteration over all items in the
1008 // dictionary and are compatible with for-each loops and standard library
1009 // algorithms.
David Van Cleve373381d2020-01-07 18:16:131010 //
Gabriel Charetteb49d73a2021-05-05 20:05:591011 // Unlike with std::map, a range-for over the non-const version of
1012 // `DictItems()` will range over items of type
1013 // `pair<const std::string&, Value&>`, so code of the form
David Van Cleve373381d2020-01-07 18:16:131014 // for (auto kv : my_value.DictItems())
1015 // Mutate(kv.second);
Gabriel Charetteb49d73a2021-05-05 20:05:591016 // will actually alter `my_value` in place (if it isn't const).
David Van Cleve373381d2020-01-07 18:16:131017 //
Daniel Cheng619653b2022-02-17 18:33:121018 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1019 // instead.
jdoerrie44efa9d2017-07-14 14:47:201020 dict_iterator_proxy DictItems();
1021 const_dict_iterator_proxy DictItems() const;
1022
Daniel Cheng619653b2022-02-17 18:33:121023 // DEPRECATED: prefer `Value::Dict::size()`.
Lei Zhange823c512018-05-07 20:27:301024 size_t DictSize() const;
Daniel Cheng619653b2022-02-17 18:33:121025
1026 // DEPRECATED: prefer `Value::Dict::empty()`.
Lei Zhange823c512018-05-07 20:27:301027 bool DictEmpty() const;
Daniel Cheng619653b2022-02-17 18:33:121028
1029 // DEPRECATED: prefer `Value::Dict::clear()`.
Panos Astithas0532a862020-10-29 04:15:071030 void DictClear();
Lei Zhange823c512018-05-07 20:27:301031
Gabriel Charetteb49d73a2021-05-05 20:05:591032 // Merge `dictionary` into this value. This is done recursively, i.e. any
jdoerriec1091282018-08-01 17:28:121033 // sub-dictionaries will be merged as well. In case of key collisions, the
1034 // passed in dictionary takes precedence and data already present will be
Gabriel Charetteb49d73a2021-05-05 20:05:591035 // replaced. Values within `dictionary` are deep-copied, so `dictionary` may
jdoerriec1091282018-08-01 17:28:121036 // be freed any time after this call.
Gabriel Charetteb49d73a2021-05-05 20:05:591037 // Note: This requires that `type()` and `dictionary->type()` is
Daniel Chenga367fe52022-02-15 18:08:481038 // Type::DICT.
Daniel Cheng619653b2022-02-17 18:33:121039 //
1040 // DEPRECATED: prefer `Value::Dict::Merge()`.
jdoerriec1091282018-08-01 17:28:121041 void MergeDictionary(const Value* dictionary);
1042
[email protected]2f03f532013-07-17 08:43:331043 // These methods allow the convenient retrieval of the contents of the Value.
1044 // If the current object can be converted into the given type, the value is
Gabriel Charetteb49d73a2021-05-05 20:05:591045 // returned through the `out_value` parameter and true is returned;
1046 // otherwise, false is returned and `out_value` is unchanged.
lukaszad1485da72016-11-01 21:49:461047 // ListValue::From is the equivalent for std::unique_ptr conversions.
Daniel Cheng619653b2022-02-17 18:33:121048 //
1049 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
1050 // `GetIfList()` otherwise.
jdoerrie8e945542017-02-17 13:54:491051 bool GetAsList(ListValue** out_value);
1052 bool GetAsList(const ListValue** out_value) const;
lukaszad1485da72016-11-01 21:49:461053 // DictionaryValue::From is the equivalent for std::unique_ptr conversions.
Daniel Cheng619653b2022-02-17 18:33:121054 //
1055 // DEPRECATED: prefer direct use `base::Value::Dict` where possible, or
1056 // `GetIfDict()` otherwise.
jdoerrie8e945542017-02-17 13:54:491057 bool GetAsDictionary(DictionaryValue** out_value);
1058 bool GetAsDictionary(const DictionaryValue** out_value) const;
[email protected]2f03f532013-07-17 08:43:331059 // Note: Do not add more types. See the file-level comment above for why.
initial.commitd7cae122008-07-26 21:49:381060
1061 // This creates a deep copy of the entire Value tree, and returns a pointer
jdoerrie05eb3162017-02-01 10:36:561062 // to the copy. The caller gets ownership of the copy, of course.
[email protected]16f47e082011-01-18 02:16:591063 // Subclasses return their own type directly in their overrides;
1064 // this works because C++ supports covariant return types.
jdoerriee964d9a2017-04-05 06:44:171065 // TODO(crbug.com/646113): Delete this and migrate callsites.
Daniel Cheng619653b2022-02-17 18:33:121066 //
1067 // DEPRECATED: prefer `Value::Clone()`.
dcheng093de9b2016-04-04 21:25:511068 std::unique_ptr<Value> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381069
jdoerrie5c1cee112017-03-28 17:52:001070 // Comparison operators so that Values can easily be used with standard
1071 // library algorithms and associative containers.
1072 BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
1073 BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs);
1074 BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs);
1075 BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs);
1076 BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
1077 BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);
1078
Daniel Cheng0b0b6752022-05-25 02:59:481079 BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs);
1080 friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; }
1081 friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); }
1082 friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); }
Daniel Cheng6b621cf2022-06-02 02:42:021083 template <typename T>
1084 friend bool operator==(const Value& lhs, const T* rhs) = delete;
1085 template <typename T>
1086 friend bool operator==(const T* lhs, const Value& rhs) = delete;
1087 template <typename T>
1088 friend bool operator!=(const Value& lhs, const T* rhs) = delete;
1089 template <typename T>
1090 friend bool operator!=(const T* lhs, const Value& rhs) = delete;
Daniel Cheng0b0b6752022-05-25 02:59:481091 BASE_EXPORT friend bool operator==(const Value& lhs, int rhs);
1092 friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; }
1093 friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); }
1094 friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); }
1095 BASE_EXPORT friend bool operator==(const Value& lhs, double rhs);
1096 friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; }
1097 friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); }
1098 friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); }
Daniel Cheng6b621cf2022-06-02 02:42:021099 // Note: StringPiece16 overload intentionally omitted: Value internally stores
1100 // strings as UTF-8. While it is possible to implement a comparison operator
1101 // that would not require first creating a new UTF-8 string from the UTF-16
1102 // string argument, it is simpler to just not implement it at all for a rare
1103 // use case.
Daniel Cheng0b0b6752022-05-25 02:59:481104 BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs);
1105 friend bool operator==(StringPiece lhs, const Value& rhs) {
1106 return rhs == lhs;
1107 }
1108 friend bool operator!=(const Value& lhs, StringPiece rhs) {
1109 return !(lhs == rhs);
1110 }
1111 friend bool operator!=(StringPiece lhs, const Value& rhs) {
1112 return !(lhs == rhs);
1113 }
Daniel Cheng6b621cf2022-06-02 02:42:021114 friend bool operator==(const Value& lhs, const char* rhs) {
1115 return lhs == StringPiece(rhs);
1116 }
1117 friend bool operator==(const char* lhs, const Value& rhs) {
1118 return rhs == lhs;
1119 }
1120 friend bool operator!=(const Value& lhs, const char* rhs) {
1121 return !(lhs == rhs);
1122 }
1123 friend bool operator!=(const char* lhs, const Value& rhs) {
1124 return !(lhs == rhs);
1125 }
1126 friend bool operator==(const Value& lhs, const std::string& rhs) {
1127 return lhs == StringPiece(rhs);
1128 }
1129 friend bool operator==(const std::string& lhs, const Value& rhs) {
1130 return rhs == lhs;
1131 }
1132 friend bool operator!=(const Value& lhs, const std::string& rhs) {
1133 return !(lhs == rhs);
1134 }
1135 friend bool operator!=(const std::string& lhs, const Value& rhs) {
1136 return !(lhs == rhs);
1137 }
Daniel Cheng0b0b6752022-05-25 02:59:481138 // Note: Blob support intentionally omitted as an experiment for potentially
1139 // wholly removing Blob support from Value itself in the future.
1140 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs);
1141 friend bool operator==(const Value::Dict& lhs, const Value& rhs) {
1142 return rhs == lhs;
1143 }
1144 friend bool operator!=(const Value& lhs, const Value::Dict& rhs) {
1145 return !(lhs == rhs);
1146 }
1147 friend bool operator!=(const Value::Dict& lhs, const Value& rhs) {
1148 return !(lhs == rhs);
1149 }
1150 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs);
1151 friend bool operator==(const Value::List& lhs, const Value& rhs) {
1152 return rhs == lhs;
1153 }
1154 friend bool operator!=(const Value& lhs, const Value::List& rhs) {
1155 return !(lhs == rhs);
1156 }
1157 friend bool operator!=(const Value::List& lhs, const Value& rhs) {
1158 return !(lhs == rhs);
1159 }
1160
initial.commitd7cae122008-07-26 21:49:381161 // Compares if two Value objects have equal contents.
Gabriel Charetteb49d73a2021-05-05 20:05:591162 // DEPRECATED, use `operator==(const Value& lhs, const Value& rhs)` instead.
jdoerrie5c1cee112017-03-28 17:52:001163 // TODO(crbug.com/646113): Delete this and migrate callsites.
Daniel Cheng619653b2022-02-17 18:33:121164 //
1165 // DEPRECATED: prefer direct use of the equality operator instead.
jdoerrie8e945542017-02-17 13:54:491166 bool Equals(const Value* other) const;
initial.commitd7cae122008-07-26 21:49:381167
Eric Secklerf6c544f2020-06-02 10:49:211168 // Estimates dynamic memory usage. Requires tracing support
1169 // (enable_base_tracing gn flag), otherwise always returns 0. See
1170 // base/trace_event/memory_usage_estimator.h for more info.
Alexander Yashkinab504e72017-11-30 11:54:451171 size_t EstimateMemoryUsage() const;
1172
Alan Cutter2dd83032020-12-08 21:55:001173 // Serializes to a string for logging and debug purposes.
1174 std::string DebugString() const;
1175
Peter Kotwicz83a231372021-04-13 17:42:121176#if BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211177 // Write this object into a trace.
Alexander Timinbebb2002021-04-20 15:42:241178 void WriteIntoTrace(perfetto::TracedValue) const;
Peter Kotwicz83a231372021-04-13 17:42:121179#endif // BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211180
Daniel Cheng8ac305b2022-02-17 00:05:111181 template <typename Visitor>
1182 auto Visit(Visitor&& visitor) const {
1183 return absl::visit(std::forward<Visitor>(visitor), data_);
1184 }
1185
jdoerrie8e945542017-02-17 13:54:491186 protected:
Jan Wilken Dörrie79d022142020-08-19 18:18:321187 // Checked convenience accessors for dict and list.
Daniel Chenga367fe52022-02-15 18:08:481188 const LegacyDictStorage& dict() const { return GetDict().storage_; }
1189 LegacyDictStorage& dict() { return GetDict().storage_; }
1190 const ListStorage& list() const { return GetList().storage_; }
1191 ListStorage& list() { return GetList().storage_; }
Jan Wilken Dörrie79d022142020-08-19 18:18:321192
Jan Wilken Dörrief961a372020-11-02 20:30:341193 // Internal constructors, allowing the simplify the implementation of Clone().
1194 explicit Value(const LegacyDictStorage& storage);
1195 explicit Value(LegacyDictStorage&& storage) noexcept;
1196
Jan Wilken Dörrie79d022142020-08-19 18:18:321197 private:
Daniel Cheng8ac305b2022-02-17 00:05:111198 // For access to DoubleStorage.
1199 friend class ValueView;
1200
David 'Digit' Turner2f287312019-04-03 14:32:091201 // Special case for doubles, which are aligned to 8 bytes on some
1202 // 32-bit architectures. In this case, a simple declaration as a
1203 // double member would make the whole union 8 byte-aligned, which
1204 // would also force 4 bytes of wasted padding space before it in
1205 // the Value layout.
David 'Digit' Turner806dedb82019-03-06 17:43:111206 //
David 'Digit' Turner2f287312019-04-03 14:32:091207 // To override this, store the value as an array of 32-bit integers, and
1208 // perform the appropriate bit casts when reading / writing to it.
Daniel Cheng6b621cf2022-06-02 02:42:021209 class BASE_EXPORT DoubleStorage {
Daniel Cheng782d2ba32022-02-16 19:40:291210 public:
1211 explicit DoubleStorage(double v);
1212 DoubleStorage(const DoubleStorage&) = default;
1213 DoubleStorage& operator=(const DoubleStorage&) = default;
1214
Daniel Cheng8ac305b2022-02-17 00:05:111215 // Provide an implicit conversion to double to simplify the use of visitors
1216 // with `Value::Visit()`. Otherwise, visitors would need a branch for
1217 // handling `DoubleStorage` like:
1218 //
1219 // value.Visit([] (const auto& member) {
1220 // using T = std::decay_t<decltype(member)>;
1221 // if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
1222 // SomeFunction(double{member});
1223 // } else {
1224 // SomeFunction(member);
1225 // }
1226 // });
Peter Kastingcc88ac052022-05-03 09:58:011227 operator double() const { return base::bit_cast<double>(v_); }
Daniel Cheng782d2ba32022-02-16 19:40:291228
1229 private:
1230 friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111231 return double{lhs} == double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291232 }
1233
1234 friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1235 return !(lhs == rhs);
1236 }
1237
1238 friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111239 return double{lhs} < double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291240 }
1241
1242 friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1243 return rhs < lhs;
1244 }
1245
1246 friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1247 return !(rhs < lhs);
1248 }
1249
1250 friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1251 return !(lhs < rhs);
1252 }
1253
1254 alignas(4) std::array<char, sizeof(double)> v_;
1255 };
David 'Digit' Turner2f287312019-04-03 14:32:091256
Jan Wilken Dörrie79d022142020-08-19 18:18:321257 // Internal constructors, allowing the simplify the implementation of Clone().
1258 explicit Value(absl::monostate);
1259 explicit Value(DoubleStorage storage);
jdoerrie8e945542017-02-17 13:54:491260
Jan Wilken Dörrie79d022142020-08-19 18:18:321261 absl::variant<absl::monostate,
1262 bool,
1263 int,
1264 DoubleStorage,
1265 std::string,
1266 BlobStorage,
Daniel Chenga367fe52022-02-15 18:08:481267 Dict,
1268 List>
Jan Wilken Dörrie79d022142020-08-19 18:18:321269 data_;
initial.commitd7cae122008-07-26 21:49:381270};
1271
[email protected]9e4cda7332010-07-31 04:56:141272// DictionaryValue provides a key-value dictionary with (optional) "path"
1273// parsing for recursive access; see the comment at the top of the file. Keys
Gabriel Charetted7c00cbe2021-05-14 20:05:531274// are std::string's and should be UTF-8 encoded.
Daniel Cheng619653b2022-02-17 18:33:121275//
1276// DEPRECATED: prefer `Value::Dict`.
[email protected]0bea7252011-08-05 15:34:001277class BASE_EXPORT DictionaryValue : public Value {
initial.commitd7cae122008-07-26 21:49:381278 public:
Gabriel Charetteb49d73a2021-05-05 20:05:591279 // Returns `value` if it is a dictionary, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511280 static std::unique_ptr<DictionaryValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541281
[email protected]3a3d47472010-07-15 21:03:541282 DictionaryValue();
Jan Wilken Dörrief961a372020-11-02 20:30:341283 explicit DictionaryValue(const LegacyDictStorage& in_dict);
1284 explicit DictionaryValue(LegacyDictStorage&& in_dict) noexcept;
[email protected]5cf906f82011-11-26 01:11:441285
initial.commitd7cae122008-07-26 21:49:381286 // Sets the Value associated with the given path starting from this object.
1287 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1288 // into the next DictionaryValue down. Obviously, "." can't be used
1289 // within a key, but there are no other restrictions on keys.
1290 // If the key at any step of the way doesn't exist, or exists but isn't
1291 // a DictionaryValue, a new DictionaryValue will be created and attached
Gabriel Charetteb49d73a2021-05-05 20:05:591292 // to the path in that location. `in_value` must be non-null.
jdoerrieb94e5422017-04-28 21:52:581293 // Returns a pointer to the inserted value.
Daniel Cheng619653b2022-02-17 18:33:121294 //
1295 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1296 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1297 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581298 Value* Set(StringPiece path, std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381299
1300 // Convenience forms of Set(). These methods will replace any existing
1301 // value at that path, even if it has a different type.
Daniel Cheng619653b2022-02-17 18:33:121302 //
1303 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1304 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1305 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581306 Value* SetBoolean(StringPiece path, bool in_value);
Daniel Cheng619653b2022-02-17 18:33:121307 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1308 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1309 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581310 Value* SetInteger(StringPiece path, int in_value);
Daniel Cheng619653b2022-02-17 18:33:121311 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1312 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1313 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581314 Value* SetDouble(StringPiece path, double in_value);
Daniel Cheng619653b2022-02-17 18:33:121315 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1316 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1317 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581318 Value* SetString(StringPiece path, StringPiece in_value);
Daniel Cheng619653b2022-02-17 18:33:121319 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1320 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1321 // otherwise.
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571322 Value* SetString(StringPiece path, const std::u16string& in_value);
Daniel Cheng619653b2022-02-17 18:33:121323 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1324 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1325 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581326 ListValue* SetList(StringPiece path, std::unique_ptr<ListValue> in_value);
[email protected]4dad9ad82009-11-25 20:47:521327
1328 // Like Set(), but without special treatment of '.'. This allows e.g. URLs to
1329 // be used as paths.
Daniel Cheng619653b2022-02-17 18:33:121330 //
1331 // DEPRECATED: prefer `Value::Dict::Set()`.
jdoerrieb94e5422017-04-28 21:52:581332 Value* SetWithoutPathExpansion(StringPiece key,
1333 std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381334
1335 // Gets the Value associated with the given path starting from this object.
1336 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1337 // into the next DictionaryValue down. If the path can be resolved
1338 // successfully, the value for the last key in the path will be returned
Gabriel Charetteb49d73a2021-05-05 20:05:591339 // through the `out_value` parameter, and the function will return true.
1340 // Otherwise, it will return false and `out_value` will be untouched.
initial.commitd7cae122008-07-26 21:49:381341 // Note that the dictionary always owns the value that's returned.
Gabriel Charetteb49d73a2021-05-05 20:05:591342 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121343 //
1344 // DEPRECATED: prefer `Value::Dict::Find()` (if the path only has one
1345 // component, i.e. has no dots), or `Value::Dict::FindByDottedPath()`
1346 // otherwise.
asvitkinedbd26533e2015-06-23 18:22:521347 bool Get(StringPiece path, const Value** out_value) const;
1348 bool Get(StringPiece path, Value** out_value);
initial.commitd7cae122008-07-26 21:49:381349
Gabriel Charetteb49d73a2021-05-05 20:05:591350 // These are convenience forms of `Get()`. The value will be retrieved
initial.commitd7cae122008-07-26 21:49:381351 // and the return value will be true if the path is valid and the value at
1352 // the end of the path can be returned in the form specified.
Gabriel Charetteb49d73a2021-05-05 20:05:591353 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121354 //
1355 // DEPRECATED: prefer `Value::Dict::FindInt()` (if the path only has one
1356 // component, i.e. has no dots), or `Value::Dict::FindIntByDottedPath()`
1357 // otherwise.
dcheng16d6f532016-08-25 16:07:111358 bool GetInteger(StringPiece path, int* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121359 // DEPRECATED: prefer `Value::Dict::FindString()` (if the path only has one
1360 // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
1361 // otherwise.
dcheng16d6f532016-08-25 16:07:111362 bool GetString(StringPiece path, std::string* out_value) const;
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571363 bool GetString(StringPiece path, std::u16string* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121364 // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
1365 // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
1366 // otherwise.
Jan Wilken Dörrie79d022142020-08-19 18:18:321367 bool GetDictionary(StringPiece path, const DictionaryValue** out_value) const;
asvitkinedbd26533e2015-06-23 18:22:521368 bool GetDictionary(StringPiece path, DictionaryValue** out_value);
Daniel Cheng619653b2022-02-17 18:33:121369 // DEPRECATED: prefer `Value::Dict::FindList()` (if the path only has one
1370 // component, i.e. has no dots), or `Value::Dict::FindListByDottedPath()`
1371 // otherwise.
dcheng16d6f532016-08-25 16:07:111372 bool GetList(StringPiece path, const ListValue** out_value) const;
1373 bool GetList(StringPiece path, ListValue** out_value);
initial.commitd7cae122008-07-26 21:49:381374
Gabriel Charetteb49d73a2021-05-05 20:05:591375 // Like `Get()`, but without special treatment of '.'. This allows e.g. URLs
1376 // to be used as paths.
Gabriel Charetteb49d73a2021-05-05 20:05:591377 // DEPRECATED, use `Value::FindDictKey(key)` instead.
[email protected]a61890e2012-07-27 22:27:111378 bool GetDictionaryWithoutPathExpansion(
dcheng16d6f532016-08-25 16:07:111379 StringPiece key,
[email protected]a61890e2012-07-27 22:27:111380 const DictionaryValue** out_value) const;
Gabriel Charetteb49d73a2021-05-05 20:05:591381 // DEPRECATED, use `Value::FindDictKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111382 bool GetDictionaryWithoutPathExpansion(StringPiece key,
[email protected]a61890e2012-07-27 22:27:111383 DictionaryValue** out_value);
Gabriel Charetteb49d73a2021-05-05 20:05:591384 // DEPRECATED, use `Value::FindListKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111385 bool GetListWithoutPathExpansion(StringPiece key,
[email protected]a61890e2012-07-27 22:27:111386 const ListValue** out_value) const;
Gabriel Charetteb49d73a2021-05-05 20:05:591387 // DEPRECATED, use `Value::FindListKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111388 bool GetListWithoutPathExpansion(StringPiece key, ListValue** out_value);
[email protected]4dad9ad82009-11-25 20:47:521389
Gabriel Charetteb49d73a2021-05-05 20:05:591390 // Makes a copy of `this` but doesn't include empty dictionaries and lists in
1391 // the copy. This never returns NULL, even if `this` itself is empty.
dcheng093de9b2016-04-04 21:25:511392 std::unique_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const;
[email protected]ec330b52009-12-02 00:20:321393
Gabriel Charetteb49d73a2021-05-05 20:05:591394 // Swaps contents with the `other` dictionary.
jdoerrie8e945542017-02-17 13:54:491395 void Swap(DictionaryValue* other);
[email protected]ec5263a2011-05-10 09:23:391396
[email protected]32c0e002011-11-08 21:26:411397 // This class provides an iterator over both keys and values in the
1398 // dictionary. It can't be used to modify the dictionary.
Daniel Cheng619653b2022-02-17 18:33:121399 //
1400 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1401 // instead.
[email protected]a34cc092012-08-10 12:45:351402 class BASE_EXPORT Iterator {
[email protected]32c0e002011-11-08 21:26:411403 public:
[email protected]a34cc092012-08-10 12:45:351404 explicit Iterator(const DictionaryValue& target);
vmpstre65942b2016-02-25 00:50:311405 Iterator(const Iterator& other);
[email protected]a8d94b42013-12-10 18:52:221406 ~Iterator();
[email protected]32c0e002011-11-08 21:26:411407
Lei Zhang10fce02f2021-05-14 18:45:081408 bool IsAtEnd() const { return it_ == target_.DictItems().end(); }
[email protected]32c0e002011-11-08 21:26:411409 void Advance() { ++it_; }
1410
1411 const std::string& key() const { return it_->first; }
Lei Zhang10fce02f2021-05-14 18:45:081412 const Value& value() const { return it_->second; }
[email protected]32c0e002011-11-08 21:26:411413
1414 private:
1415 const DictionaryValue& target_;
Lei Zhang10fce02f2021-05-14 18:45:081416 detail::const_dict_iterator it_;
[email protected]32c0e002011-11-08 21:26:411417 };
1418
Daniel Cheng619653b2022-02-17 18:33:121419 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerriee964d9a2017-04-05 06:44:171420 // TODO(crbug.com/646113): Delete this and migrate callsites.
jdoerrie8e945542017-02-17 13:54:491421 DictionaryValue* DeepCopy() const;
Daniel Cheng619653b2022-02-17 18:33:121422 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerried4b852612017-06-06 11:48:431423 // TODO(crbug.com/646113): Delete this and migrate callsites.
dcheng093de9b2016-04-04 21:25:511424 std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381425};
1426
1427// This type of Value represents a list of other Value values.
Daniel Cheng619653b2022-02-17 18:33:121428//
1429// DEPRECATED: prefer `base::Value::List`.
[email protected]0bea7252011-08-05 15:34:001430class BASE_EXPORT ListValue : public Value {
initial.commitd7cae122008-07-26 21:49:381431 public:
Jan Wilken Dörrie46992f022020-02-20 11:25:471432 using const_iterator = ListView::const_iterator;
1433 using iterator = ListView::iterator;
[email protected]a502bbe72011-01-07 18:06:451434
Gabriel Charetteb49d73a2021-05-05 20:05:591435 // Returns `value` if it is a list, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511436 static std::unique_ptr<ListValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541437
[email protected]3a3d47472010-07-15 21:03:541438 ListValue();
Jan Wilken Dörrie53e009b2019-09-09 14:17:411439 explicit ListValue(span<const Value> in_list);
jdoerrie52939ed2017-04-26 18:19:421440 explicit ListValue(ListStorage&& in_list) noexcept;
initial.commitd7cae122008-07-26 21:49:381441
Gabriel Charetteb49d73a2021-05-05 20:05:591442 // Convenience forms of `Get()`. Modifies `out_value` (and returns true)
[email protected]35213ce92010-04-08 19:06:151443 // only if the index is valid and the Value at that index can be returned
1444 // in the specified form.
Gabriel Charetteb49d73a2021-05-05 20:05:591445 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121446 //
1447 // DEPRECATED: prefer `Value::List::operator[]` + `GetIfDict()`.
[email protected]5d30f92bf2012-08-03 08:43:371448 bool GetDictionary(size_t index, const DictionaryValue** out_value) const;
1449 bool GetDictionary(size_t index, DictionaryValue** out_value);
jdoerrie52939ed2017-04-26 18:19:421450
initial.commitd7cae122008-07-26 21:49:381451 // Appends a Value to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:121452 // DEPRECATED: prefer `Value::List::Append()`.
1453 using Value::Append;
Daniel Chengedfa5202022-04-15 00:09:591454 // DEPRECATED: prefer `Value::List::Append()`. Provided to simplify
1455 // incremental migration and intentionally only defined on ListValue and not
1456 // Value.
1457 void Append(base::Value::Dict in_dict);
1458 void Append(base::Value::List in_list);
initial.commitd7cae122008-07-26 21:49:381459
Gabriel Charetteb49d73a2021-05-05 20:05:591460 // Swaps contents with the `other` list.
Daniel Cheng619653b2022-02-17 18:33:121461 //
1462 // DEPRECATED: prefer `base::Value::List` + `std::swap()`.
jdoerrie8e945542017-02-17 13:54:491463 void Swap(ListValue* other);
[email protected]8b8e7c92010-08-19 18:05:561464
Daniel Cheng619653b2022-02-17 18:33:121465 // Iteration: Use a range-based for loop over `base::Value::List` directly
1466 // instead.
initial.commitd7cae122008-07-26 21:49:381467};
1468
Daniel Cheng8ac305b2022-02-17 00:05:111469// Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
1470// serialization methods without having to clone the contents and transfer
1471// ownership of the clone to a `Value` wrapper object.
1472//
1473// Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
1474// underlying object that is passed by reference (i.e. `std::string`,
1475// `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
1476// live as long as there is a `ValueView` referencing it.
1477//
1478// While it might be nice to just use the `absl::variant` type directly, the
1479// need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
1480// `std::reference_wrapper` both support implicit construction, but C++ only
1481// allows at most one user-defined conversion in an implicit conversion
1482// sequence. If this adapter and its implicit constructors did not exist,
1483// callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
1484// `Value::List` to a function with a `ValueView` parameter.
1485class BASE_EXPORT GSL_POINTER ValueView {
1486 public:
Daniel Cheng6b621cf2022-06-02 02:42:021487 ValueView() = default;
Daniel Cheng8ac305b2022-02-17 00:05:111488 ValueView(bool value) : data_view_(value) {}
Daniel Cheng6b621cf2022-06-02 02:42:021489 template <typename T>
1490 ValueView(const T*) = delete;
Daniel Cheng8ac305b2022-02-17 00:05:111491 ValueView(int value) : data_view_(value) {}
1492 ValueView(double value)
1493 : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
Daniel Cheng6b621cf2022-06-02 02:42:021494 ValueView(StringPiece value) : data_view_(value) {}
1495 ValueView(const char* value) : ValueView(StringPiece(value)) {}
1496 ValueView(const std::string& value) : ValueView(StringPiece(value)) {}
1497 // Note: UTF-16 is intentionally not supported. ValueView is intended to be a
1498 // low-cost view abstraction, but Value internally represents strings as
1499 // UTF-8, so it would not be possible to implement this without allocating an
1500 // entirely new UTF-8 string.
Daniel Cheng8ac305b2022-02-17 00:05:111501 ValueView(const Value::BlobStorage& value) : data_view_(value) {}
1502 ValueView(const Value::Dict& value) : data_view_(value) {}
1503 ValueView(const Value::List& value) : data_view_(value) {}
1504 ValueView(const Value& value);
1505
Daniel Cheng6b621cf2022-06-02 02:42:021506 // This is the only 'getter' method provided as `ValueView` is not intended
1507 // to be a general replacement of `Value`.
Daniel Cheng8ac305b2022-02-17 00:05:111508 template <typename Visitor>
1509 auto Visit(Visitor&& visitor) const {
1510 return absl::visit(std::forward<Visitor>(visitor), data_view_);
1511 }
1512
1513 private:
1514 using ViewType =
1515 absl::variant<absl::monostate,
1516 bool,
1517 int,
1518 Value::DoubleStorage,
Daniel Cheng6b621cf2022-06-02 02:42:021519 StringPiece,
Daniel Cheng8ac305b2022-02-17 00:05:111520 std::reference_wrapper<const Value::BlobStorage>,
1521 std::reference_wrapper<const Value::Dict>,
1522 std::reference_wrapper<const Value::List>>;
1523
Daniel Cheng6b621cf2022-06-02 02:42:021524 public:
1525 using DoubleStorageForTest = Value::DoubleStorage;
1526 const ViewType& data_view_for_test() const { return data_view_; }
1527
1528 private:
Daniel Cheng8ac305b2022-02-17 00:05:111529 ViewType data_view_;
1530};
1531
prashhir54a994502015-03-05 09:30:571532// This interface is implemented by classes that know how to serialize
1533// Value objects.
[email protected]0bea7252011-08-05 15:34:001534class BASE_EXPORT ValueSerializer {
initial.commitd7cae122008-07-26 21:49:381535 public:
[email protected]3a3d47472010-07-15 21:03:541536 virtual ~ValueSerializer();
[email protected]abb9d0c2008-08-06 15:46:591537
Daniel Cheng8ac305b2022-02-17 00:05:111538 virtual bool Serialize(ValueView root) = 0;
prashhir54a994502015-03-05 09:30:571539};
1540
1541// This interface is implemented by classes that know how to deserialize Value
1542// objects.
1543class BASE_EXPORT ValueDeserializer {
1544 public:
1545 virtual ~ValueDeserializer();
initial.commitd7cae122008-07-26 21:49:381546
1547 // This method deserializes the subclass-specific format into a Value object.
[email protected]b4cebf82008-12-29 19:59:081548 // If the return value is non-NULL, the caller takes ownership of returned
Nigel Tao410788e2020-06-24 07:12:271549 // Value.
1550 //
Gabriel Charetteb49d73a2021-05-05 20:05:591551 // If the return value is nullptr, and if `error_code` is non-nullptr,
1552 // `*error_code` will be set to an integer value representing the underlying
Nigel Tao410788e2020-06-24 07:12:271553 // error. See "enum ErrorCode" below for more detail about the integer value.
1554 //
Gabriel Charetteb49d73a2021-05-05 20:05:591555 // If `error_message` is non-nullptr, it will be filled in with a formatted
[email protected]ba399672010-04-06 15:42:391556 // error message including the location of the error if appropriate.
dcheng093de9b2016-04-04 21:25:511557 virtual std::unique_ptr<Value> Deserialize(int* error_code,
Nigel Tao410788e2020-06-24 07:12:271558 std::string* error_message) = 0;
1559
1560 // The integer-valued error codes form four groups:
1561 // - The value 0 means no error.
1562 // - Values between 1 and 999 inclusive mean an error in the data (i.e.
1563 // content). The bytes being deserialized are not in the right format.
1564 // - Values 1000 and above mean an error in the metadata (i.e. context). The
1565 // file could not be read, the network is down, etc.
1566 // - Negative values are reserved.
Caitlin Fischeraac06dc2021-12-17 00:21:321567 //
1568 // These values are persisted to logs. Entries should not be renumbered and
1569 // numeric values should never be reused.
Nigel Tao410788e2020-06-24 07:12:271570 enum ErrorCode {
1571 kErrorCodeNoError = 0,
1572 // kErrorCodeInvalidFormat is a generic error code for "the data is not in
1573 // the right format". Subclasses of ValueDeserializer may return other
1574 // values for more specific errors.
1575 kErrorCodeInvalidFormat = 1,
1576 // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
1577 // range of metadata errors.
1578 kErrorCodeFirstMetadataError = 1000,
1579 };
1580
Gabriel Charetteb49d73a2021-05-05 20:05:591581 // The `error_code` argument can be one of the ErrorCode values, but it is
Nigel Tao410788e2020-06-24 07:12:271582 // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
1583 // can define their own error code values.
1584 static inline bool ErrorCodeIsDataError(int error_code) {
1585 return (kErrorCodeInvalidFormat <= error_code) &&
1586 (error_code < kErrorCodeFirstMetadataError);
1587 }
initial.commitd7cae122008-07-26 21:49:381588};
1589
Daniel Chenga367fe52022-02-15 18:08:481590// Stream operator so Values can be pretty printed by gtest.
[email protected]e4ef8312012-09-12 03:39:351591BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
Daniel Chenga367fe52022-02-15 18:08:481592BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1593 const Value::Dict& dict);
1594BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1595 const Value::List& list);
[email protected]e4ef8312012-09-12 03:39:351596
Daniel Chenga367fe52022-02-15 18:08:481597// Hints for DictionaryValue and ListValue; otherwise, gtest tends to prefer the
1598// default template implementation over an upcast to Value.
[email protected]ea0ec052013-04-16 09:04:021599BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
[email protected]ea0ec052013-04-16 09:04:021600 const DictionaryValue& value) {
1601 return out << static_cast<const Value&>(value);
1602}
1603
1604BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
1605 const ListValue& value) {
1606 return out << static_cast<const Value&>(value);
1607}
1608
jdoerriedc72ee942016-12-07 15:43:281609// Stream operator so that enum class Types can be used in log statements.
1610BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1611 const Value::Type& type);
1612
[email protected]f3a1c642011-07-12 19:15:031613} // namespace base
1614
[email protected]101d5422008-09-26 20:22:421615#endif // BASE_VALUES_H_