blob: 657d0d11f64de7ea02ee712e48f423b50b2db333 [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
Li-Yu Yu24e6c7b2022-08-25 04:30:4336class DictAdapterForMigration;
initial.commitd7cae122008-07-26 21:49:3837class DictionaryValue;
38class ListValue;
39
Daniel Chenga367fe52022-02-15 18:08:4840// The `Value` class is a variant type can hold one of the following types:
41// - null
42// - bool
43// - int
44// - double
45// - string (internally UTF8-encoded)
46// - binary data (i.e. a blob)
47// - dictionary of string keys to `Value`s
48// - list of `Value`s
[email protected]2f03f532013-07-17 08:43:3349//
Daniel Chenga367fe52022-02-15 18:08:4850// With the exception of binary blobs, `Value` is intended to be the C++ version
51// of data types that can be represented in JSON.
Brett Wilson4bef8ee2017-09-01 20:11:4952//
Daniel Chenga367fe52022-02-15 18:08:4853// Warning: blob support may be removed in the future.
54//
55// ## Usage
56//
57// Do not use `Value` if a more specific type would be more appropriate. For
58// example, a function that only accepts dictionary values should have a
59// `base::Value::Dict` parameter, not a `base::Value` parameter.
60//
61// Construction:
62//
63// `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
64// (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
65// `Value::Dict`, and `Value::List`.
66//
67// Copying:
68//
69// `Value` does not support C++ copy semantics to make it harder to accidentally
70// copy large values. Instead, use `Clone()` to manually create a deep copy.
71//
72// Reading:
73//
74// `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
75// subtype before returning the contained value. `bool`, `int`, `double` are
76// returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
77// are returned by reference.
78//
79// `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
80// the `Value` does not have the correct subtype; otherwise, returns the value
81// wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
82// (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
83//
84// Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
85// when the subtype is `Value::Type::INT`. In that case, the stored value is
86// coerced to a double before being returned.
87//
88// Assignment:
89//
90// It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
91// Instead, wrap the underlying type in `Value` before assigning.
92//
93// ## Dictionaries and Lists
94//
95// `Value` provides the `Value::Dict` and `Value::List` container types for
96// working with dictionaries and lists of values respectively, rather than
97// exposing the underlying container types directly. This allows the types to
98// provide convenient helpers for dictionaries and lists, as well as giving
99// greater flexibility for changing implementation details in the future.
100//
101// Both container types support enough STL-isms to be usable in range-based for
102// loops and generic operations such as those from <algorithm>.
103//
104// Dictionaries support:
105// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
106// `contains()`, `clear()`, `erase()`: Identical to the STL container
107// equivalents, with additional safety checks, e.g. iterators will
108// `CHECK()` if `end()` is dereferenced.
109//
110// - `Clone()`: Create a deep copy.
111// - `Merge()`: Merge another dictionary into this dictionary.
112// - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
113// is not present.
114// - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
115// `Value` also has the correct subtype. Same return semantics as
116// `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
117// `nullptr` if the key is not present or the value has the wrong subtype.
118// - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
119// of the subtypes that `Value` can hold.
120// - `Remove()`: Remove the key from this dictionary, if present.
121// - `Extract()`: If the key is present in the dictionary, removes the key from
122// the dictionary and transfers ownership of `Value` to the caller.
123// Otherwise, returns `absl::nullopt`.
124//
125// Dictionaries also support an additional set of helper methods that operate on
126// "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
127// and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
128// intermediate nested dictionaries, separating the components of the path using
129// '.' characters. For example, finding a string path on a `Value::Dict` using
130// the dotted path:
131//
132// "aaa.bbb.ccc"
133//
134// Will first look for a `Value::Type::DICT` associated with the key "aaa", then
135// another `Value::Type::DICT` under the "aaa" dict associated with the
136// key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
137// with the key "ccc".
138//
Daniel Cheng619653b2022-02-17 18:33:12139// If a path only has one component (i.e. has no dots), please use the regular,
140// non-path APIs.
141//
Daniel Chenga367fe52022-02-15 18:08:48142// Lists support:
143// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
Daniel Chengc9ab0ef2022-02-18 02:34:07144// `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`:
145// Identical to the STL container equivalents, with additional safety
146// checks, e.g. `operator[]` will `CHECK()` if the index is out of range.
Daniel Chenga367fe52022-02-15 18:08:48147// - `Clone()`: Create a deep copy.
148// - `Append()`: Append a value to the end of the list. Accepts `Value` or any
149// of the subtypes that `Value` can hold.
150// - `Insert()`: Insert a `Value` at a specified point in the list.
151// - `EraseValue()`: Erases all matching `Value`s from the list.
152// - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
153// list.
154//
155// ## Refactoring Notes
156//
157// `Value` was originally implemented as a class hierarchy, with a `Value` base
158// class, and a leaf class for each of the different types of `Value` subtypes.
Brett Wilson4bef8ee2017-09-01 20:11:49159// https://docs.google.com/document/d/1uDLu5uTRlCWePxQUEHc8yNQdEoE1BDISYdpggWEABnw
Daniel Chenga367fe52022-02-15 18:08:48160// proposed an overhaul of the `Value` API that has now largely been
161// implemented, though there remains a significant amount of legacy code that is
162// still being migrated as part of the code health migration.
Brett Wilson4bef8ee2017-09-01 20:11:49163//
164// OLD WAY:
165//
166// std::unique_ptr<base::Value> GetFoo() {
167// std::unique_ptr<DictionaryValue> dict;
Daniel Chenga367fe52022-02-15 18:08:48168// dict->SetString("mykey", "foo");
Brett Wilson4bef8ee2017-09-01 20:11:49169// return dict;
170// }
171//
Brett Wilson4bef8ee2017-09-01 20:11:49172// NEW WAY:
173//
174// base::Value GetFoo() {
Daniel Chenga367fe52022-02-15 18:08:48175// base::Value::Dict dict;
Scott Haseley5fd36262022-03-04 19:35:11176// dict.Set("mykey", "abc");
Daniel Chenga367fe52022-02-15 18:08:48177// return base::Value(std::move(dict));
Brett Wilson4bef8ee2017-09-01 20:11:49178// }
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04179//
Daniel Chenga367fe52022-02-15 18:08:48180// To avoid losing type information with the new variant-based design, migration
181// off the deprecated types should use more specific subtypes where possible:
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04182//
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49183// OLD WAY:
184//
185// void AlwaysTakesList(std::unique_ptr<base::ListValue> list);
186// void AlwaysTakesDict(std::unique_ptr<base::DictionaryValue> dict);
187//
Daniel Chenga367fe52022-02-15 18:08:48188// DEPRECATED (PREVIOUS) WAY:
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49189//
190// void AlwaysTakesList(std::vector<base::Value> list);
Daniel Chenga367fe52022-02-15 18:08:48191// void AlwaysTakesListAlternative1(base::Value::ConstListView list);
192// void AlwaysTakesListAlternative2(base::Value::ListView& list);
193// void AlwaysTakesListAlterantive3(base::Value::ListStorage);
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49194// void AlwaysTakesDict(base::flat_map<std::string, base::Value> dict);
Daniel Chenga367fe52022-02-15 18:08:48195// void AlwaysTakesDictAlternative(base::Value::DictStorage);
Daniel Cheng60e6b2d2022-02-05 01:08:46196//
197// NEW WAY:
198//
Daniel Chenga367fe52022-02-15 18:08:48199// void AlwaysTakesList(base::Value::List list);
200// void AlwaysTakesDict(base::Value::Dict dict);
Daniel Cheng60e6b2d2022-02-05 01:08:46201//
Daniel Chenga367fe52022-02-15 18:08:48202// Migrating code may require conversions on API boundaries. If something seems
203// awkward/inefficient, please reach out to #code-health-rotation on Slack for
204// consultation: it is entirely possible that certain classes of APIs may be
205// missing due to an unrealized need.
Daniel Cheng8ac305b2022-02-17 00:05:11206class BASE_EXPORT GSL_OWNER Value {
initial.commitd7cae122008-07-26 21:49:38207 public:
jdoerrie9970f20e2018-07-20 21:41:18208 using BlobStorage = std::vector<uint8_t>;
Daniel Cheng773ce4502022-01-28 15:25:06209
210 using DeprecatedListStorage = std::vector<Value>;
Jan Wilken Dörrief961a372020-11-02 20:30:34211
212 // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is
Matt Menkee311c6d2022-06-14 20:17:39213 // due to legacy reasons, and should be replaced with
214 // flat_map<std::string, Value> once no caller relies on stability of pointers
Matt Menke167ca682022-06-08 23:19:28215 // anymore.
Jan Wilken Dörrief961a372020-11-02 20:30:34216 using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57217
Matt Menke06842489d2022-07-22 00:04:33218 using DeprecatedListView = CheckedContiguousRange<DeprecatedListStorage>;
219 using DeprecatedConstListView =
220 CheckedContiguousConstRange<DeprecatedListStorage>;
Daniel Cheng773ce4502022-01-28 15:25:06221 // 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
jdoerrie8e945542017-02-17 13:54:49305 ~Value();
jdoerrie05eb3162017-02-01 10:36:56306
Gabriel Charetteb49d73a2021-05-05 20:05:59307 // Returns the name for a given `type`.
thestig61709242016-07-19 00:39:30308 static const char* GetTypeName(Type type);
309
initial.commitd7cae122008-07-26 21:49:38310 // Returns the type of the value stored by the current Value object.
Jan Wilken Dörrie79d022142020-08-19 18:18:32311 Type type() const { return static_cast<Type>(data_.index()); }
initial.commitd7cae122008-07-26 21:49:38312
313 // Returns true if the current object represents a given type.
jdoerriecc9f5732017-08-23 14:12:30314 bool is_none() const { return type() == Type::NONE; }
jdoerrie05eb3162017-02-01 10:36:56315 bool is_bool() const { return type() == Type::BOOLEAN; }
316 bool is_int() const { return type() == Type::INTEGER; }
317 bool is_double() const { return type() == Type::DOUBLE; }
318 bool is_string() const { return type() == Type::STRING; }
319 bool is_blob() const { return type() == Type::BINARY; }
Daniel Chenga367fe52022-02-15 18:08:48320 bool is_dict() const { return type() == Type::DICT; }
jdoerrie05eb3162017-02-01 10:36:56321 bool is_list() const { return type() == Type::LIST; }
322
Daniel Chenga367fe52022-02-15 18:08:48323 // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
324 // otherwise. `bool`, `int`, and `double` are returned in a wrapped
325 // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
326 // pointer.
Anton Bikineev7dd58ad2021-05-18 01:01:39327 absl::optional<bool> GetIfBool() const;
328 absl::optional<int> GetIfInt() const;
Daniel Chenga367fe52022-02-15 18:08:48329 // Returns a non-null value for both `Value::Type::DOUBLE` and
330 // `Value::Type::INT`, converting the latter to a double.
Anton Bikineev7dd58ad2021-05-18 01:01:39331 absl::optional<double> GetIfDouble() const;
Jan Wilken Dörrie2e125622021-02-17 10:52:53332 const std::string* GetIfString() const;
Daniel Chenga367fe52022-02-15 18:08:48333 std::string* GetIfString();
Jan Wilken Dörrie2e125622021-02-17 10:52:53334 const BlobStorage* GetIfBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48335 const Dict* GetIfDict() const;
336 Dict* GetIfDict();
337 const List* GetIfList() const;
338 List* GetIfList();
Jan Wilken Dörrie2e125622021-02-17 10:52:53339
Daniel Chenga367fe52022-02-15 18:08:48340 // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
341 // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
342 // `Value::Dict`, and `Value::List` are returned by reference.
jdoerrie05eb3162017-02-01 10:36:56343 bool GetBool() const;
344 int GetInt() const;
Daniel Chenga367fe52022-02-15 18:08:48345 // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
346 // converting the latter to a double.
347 double GetDouble() const;
Daniel Cheng1cdf99782022-06-29 19:25:58348 // Callers that want to transfer ownership can use std::move() in conjunction
349 // with one of the mutable variants below, e.g.:
350 // std::string taken_string = std::move(value.GetString());
351 // base::Value::Dict taken_dict = std::move(value.GetDict());
352 // base::Value::List taken_list = std::move(value.GetList());
jdoerrief38f37b2017-02-01 14:38:32353 const std::string& GetString() const;
Dominic Battre08cbe972019-07-31 03:57:19354 std::string& GetString();
jdoerrie5f12b6272017-04-18 10:22:41355 const BlobStorage& GetBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48356 const Dict& GetDict() const;
357 Dict& GetDict();
358 const List& GetList() const;
359 List& GetList();
360
361 // Represents a dictionary of string keys to Values.
Daniel Cheng8ac305b2022-02-17 00:05:11362 class BASE_EXPORT GSL_OWNER Dict {
Daniel Chenga367fe52022-02-15 18:08:48363 public:
364 using iterator = detail::dict_iterator;
365 using const_iterator = detail::const_dict_iterator;
366
367 Dict();
368
369 Dict(Dict&&) noexcept;
370 Dict& operator=(Dict&&) noexcept;
371
372 // Deleted to prevent accidental copying.
373 Dict(const Dict&) = delete;
374 Dict& operator=(const Dict&) = delete;
375
Matt Menkee311c6d2022-06-14 20:17:39376 // Takes move_iterators iterators that return std::pair<std::string, Value>,
377 // and moves their values into a new Dict. Adding all entries at once
378 // results in a faster initial sort operation. Takes move iterators to avoid
379 // having to clone the input.
380 template <class IteratorType>
381 explicit Dict(std::move_iterator<IteratorType> first,
382 std::move_iterator<IteratorType> last) {
383 // Need to move into a vector first, since `storage_` currently uses
384 // unique_ptrs.
385 std::vector<std::pair<std::string, std::unique_ptr<Value>>> values;
386 for (auto current = first; current != last; ++current) {
387 // With move iterators, no need to call Clone(), but do need to move
388 // to a temporary first, as accessing either field individually will
389 // directly from the iterator will delete the other field.
390 auto value = *current;
391 values.emplace_back(std::move(value.first),
392 std::make_unique<Value>(std::move(value.second)));
393 }
394 storage_ =
395 flat_map<std::string, std::unique_ptr<Value>>(std::move(values));
396 }
397
Daniel Chenga367fe52022-02-15 18:08:48398 ~Dict();
399
400 // TODO(dcheng): Probably need to allow construction from a pair of
401 // iterators for now due to the prevalence of DictStorage.
402
403 // Returns true if there are no entries in this dictionary and false
404 // otherwise.
405 bool empty() const;
406
407 // Returns the number of entries in this dictionary.
408 size_t size() const;
409
410 // Returns an iterator to the first entry in this dictionary.
411 iterator begin();
412 const_iterator begin() const;
413 const_iterator cbegin() const;
414
415 // Returns an iterator following the last entry in this dictionary. May not
416 // be dereferenced.
417 iterator end();
418 const_iterator end() const;
419 const_iterator cend() const;
420
421 // Returns true if `key` is an entry in this dictionary.
422 bool contains(base::StringPiece key) const;
423
424 // Removes all entries from this dictionary.
425 void clear();
426
427 // Removes the entry referenced by `pos` in this dictionary and returns an
428 // iterator to the entry following the removed entry.
429 iterator erase(iterator pos);
430 iterator erase(const_iterator pos);
431
432 // Creates a deep copy of this dictionary.
433 Dict Clone() const;
434
435 // Merges the entries from `dict` into this dictionary. If an entry with the
436 // same key exists in this dictionary and `dict`:
437 // - if both entries are dictionaries, they will be recursively merged
438 // - otherwise, the already-existing entry in this dictionary will be
439 // overwritten with the entry from `dict`.
Daniel Cheng1cdf99782022-06-29 19:25:58440 void Merge(Dict dict);
Daniel Chenga367fe52022-02-15 18:08:48441
442 // Finds the entry corresponding to `key` in this dictionary. Returns
443 // nullptr if there is no such entry.
444 const Value* Find(StringPiece key) const;
445 Value* Find(StringPiece key);
446
447 // Similar to `Find()` above, but returns `absl::nullopt`/`nullptr` if the
448 // type of the entry does not match. `bool`, `int`, and `double` are
449 // returned in a wrapped `absl::optional`; blobs, `Value::Dict`, and
450 // `Value::List` are returned by pointer.
451 absl::optional<bool> FindBool(StringPiece key) const;
452 absl::optional<int> FindInt(StringPiece key) const;
453 // Returns a non-null value for both `Value::Type::DOUBLE` and
454 // `Value::Type::INT`, converting the latter to a double.
455 absl::optional<double> FindDouble(StringPiece key) const;
456 const std::string* FindString(StringPiece key) const;
457 std::string* FindString(StringPiece key);
458 const BlobStorage* FindBlob(StringPiece key) const;
459 const Dict* FindDict(StringPiece key) const;
460 Dict* FindDict(StringPiece key);
461 const List* FindList(StringPiece key) const;
462 List* FindList(StringPiece key);
463
Matt Menkef8f453e2022-08-09 17:52:02464 // If there's a value of the specified type at `key` in this dictionary,
465 // returns it. Otherwise, creates an empty container of the specified type,
466 // inserts it at `key`, and returns it. If there's a value of some other
467 // type at `key`, will overwrite that entry.
468 Dict* EnsureDict(StringPiece key);
469 List* EnsureList(StringPiece key);
470
Daniel Chenga367fe52022-02-15 18:08:48471 // Sets an entry with `key` and `value` in this dictionary, overwriting any
472 // existing entry with the same `key`. Returns a pointer to the set `value`.
473 Value* Set(StringPiece key, Value&& value);
474 Value* Set(StringPiece key, bool value);
475 template <typename T>
476 Value* Set(StringPiece, const T*) = delete;
477 Value* Set(StringPiece key, int value);
478 Value* Set(StringPiece key, double value);
479 Value* Set(StringPiece key, StringPiece value);
480 Value* Set(StringPiece key, StringPiece16 value);
481 Value* Set(StringPiece key, const char* value);
482 Value* Set(StringPiece key, const char16_t* value);
483 Value* Set(StringPiece key, std::string&& value);
484 Value* Set(StringPiece key, BlobStorage&& value);
485 Value* Set(StringPiece key, Dict&& value);
486 Value* Set(StringPiece key, List&& value);
487
488 // Removes the entry corresponding to `key` from this dictionary. Returns
489 // true if an entry was removed or false otherwise.
490 bool Remove(StringPiece key);
491
492 // Similar to `Remove()`, but returns the value corresponding to the removed
493 // entry or `absl::nullopt` otherwise.
494 absl::optional<Value> Extract(StringPiece key);
495
496 // Equivalent to the above methods but operating on paths instead of keys.
497 // A path is shorthand syntax for referring to a key nested inside
498 // intermediate dictionaries, with components delimited by ".". Paths may
499 // not be empty.
500 //
Daniel Cheng619653b2022-02-17 18:33:12501 // Prefer the non-path methods above when possible. Paths that have only one
502 // component (i.e. no dots in the path) should never use the path-based
503 // methods.
504 //
505 // Originally, the path-based APIs were the only way of specifying a key, so
506 // there are likely to be many legacy (and unnecessary) uses of the path
507 // APIs that do not actually require traversing nested dictionaries.
Daniel Chenga367fe52022-02-15 18:08:48508 const Value* FindByDottedPath(StringPiece path) const;
509 Value* FindByDottedPath(StringPiece path);
510
511 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
512 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
513 // Returns a non-null value for both `Value::Type::DOUBLE` and
514 // `Value::Type::INT`, converting the latter to a double.
515 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
516 const std::string* FindStringByDottedPath(StringPiece path) const;
517 std::string* FindStringByDottedPath(StringPiece path);
518 const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
519 const Dict* FindDictByDottedPath(StringPiece path) const;
520 Dict* FindDictByDottedPath(StringPiece path);
521 const List* FindListByDottedPath(StringPiece path) const;
522 List* FindListByDottedPath(StringPiece path);
523
Daniel Cheng619653b2022-02-17 18:33:12524 // Creates a new entry with a dictionary for any non-last component that is
525 // missing an entry while performing the path traversal. Will fail if any
526 // non-last component of the path refers to an already-existing entry that
527 // is not a dictionary. Returns `nullptr` on failure.
Daniel Chenga367fe52022-02-15 18:08:48528 Value* SetByDottedPath(StringPiece path, Value&& value);
529 Value* SetByDottedPath(StringPiece path, bool value);
530 template <typename T>
531 Value* SetByDottedPath(StringPiece, const T*) = delete;
532 Value* SetByDottedPath(StringPiece path, int value);
533 Value* SetByDottedPath(StringPiece path, double value);
534 Value* SetByDottedPath(StringPiece path, StringPiece value);
535 Value* SetByDottedPath(StringPiece path, StringPiece16 value);
536 Value* SetByDottedPath(StringPiece path, const char* value);
537 Value* SetByDottedPath(StringPiece path, const char16_t* value);
538 Value* SetByDottedPath(StringPiece path, std::string&& value);
539 Value* SetByDottedPath(StringPiece path, BlobStorage&& value);
540 Value* SetByDottedPath(StringPiece path, Dict&& value);
541 Value* SetByDottedPath(StringPiece path, List&& value);
542
543 bool RemoveByDottedPath(StringPiece path);
544
545 absl::optional<Value> ExtractByDottedPath(StringPiece path);
546
Scott Haseleye51040782022-03-09 17:32:37547 // Serializes to a string for logging and debug purposes.
548 std::string DebugString() const;
549
Daniel Chengb5862bc2022-06-09 17:04:06550#if BUILDFLAG(ENABLE_BASE_TRACING)
551 // Write this object into a trace.
552 void WriteIntoTrace(perfetto::TracedValue) const;
553#endif // BUILDFLAG(ENABLE_BASE_TRACING)
554
Daniel Chenga367fe52022-02-15 18:08:48555 private:
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 BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
560 BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
561 BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);
562
563 // For legacy access to the internal storage type.
564 friend Value;
565
566 explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);
567
568 flat_map<std::string, std::unique_ptr<Value>> storage_;
569 };
570
571 // Represents a list of Values.
Daniel Cheng8ac305b2022-02-17 00:05:11572 class BASE_EXPORT GSL_OWNER List {
Daniel Chenga367fe52022-02-15 18:08:48573 public:
574 using iterator = CheckedContiguousIterator<Value>;
575 using const_iterator = CheckedContiguousConstIterator<Value>;
Jan Keitel56a92682022-07-11 11:19:21576 using value_type = Value;
Daniel Chenga367fe52022-02-15 18:08:48577
578 List();
579
580 List(List&&) noexcept;
581 List& operator=(List&&) noexcept;
582
583 // Deleted to prevent accidental copying.
584 List(const List&) = delete;
585 List& operator=(const List&) = delete;
586
587 ~List();
588
589 // TODO(dcheng): Probably need to allow construction from a pair of
590 // iterators for now due to the prevalence of ListStorage now.
591
592 // Returns true if there are no values in this list and false otherwise.
593 bool empty() const;
594
595 // Returns the number of values in this list.
596 size_t size() const;
597
598 // Returns an iterator to the first value in this list.
599 iterator begin();
600 const_iterator begin() const;
601 const_iterator cbegin() const;
602
603 // Returns an iterator following the last value in this list. May not be
604 // dereferenced.
605 iterator end();
606 const_iterator end() const;
607 const_iterator cend() const;
608
Daniel Chengc9ab0ef2022-02-18 02:34:07609 // Returns a reference to the first value in the container. Fails with
610 // `CHECK()` if the list is empty.
611 const Value& front() const;
612 Value& front();
613
614 // Returns a reference to the last value in the container. Fails with
615 // `CHECK()` if the list is empty.
616 const Value& back() const;
617 Value& back();
618
619 // Increase the capacity of the backing container, but does not change
620 // the size. Assume all existing iterators will be invalidated.
621 void reserve(size_t capacity);
622
Daniel Chenga367fe52022-02-15 18:08:48623 // Returns a reference to the value at `index` in this list. Fails with a
624 // `CHECK()` if `index >= size()`.
625 const Value& operator[](size_t index) const;
626 Value& operator[](size_t index);
627
628 // Removes all value from this list.
629 void clear();
630
Daniel Chengc9ab0ef2022-02-18 02:34:07631 // Removes the value referenced by `pos` in this list and returns an
632 // iterator to the value following the removed value.
Daniel Chenga367fe52022-02-15 18:08:48633 iterator erase(iterator pos);
634 const_iterator erase(const_iterator pos);
635
Matt Menke3a0de712022-07-14 23:45:08636 // Remove the values in the range [`first`, `last`). Returns iterator to the
637 // first value following the removed range, which is `last`. If `first` ==
638 // `last`, removes nothing and returns `last`.
639 iterator erase(iterator first, iterator last);
640 const_iterator erase(const_iterator first, const_iterator last);
641
Daniel Chenga367fe52022-02-15 18:08:48642 // Creates a deep copy of this dictionary.
643 List Clone() const;
644
645 // Appends `value` to the end of this list.
646 void Append(Value&& value);
647 void Append(bool value);
648 template <typename T>
649 void Append(const T*) = delete;
650 void Append(int value);
651 void Append(double value);
652 void Append(StringPiece value);
653 void Append(StringPiece16 value);
654 void Append(const char* value);
655 void Append(const char16_t* value);
656 void Append(std::string&& value);
657 void Append(BlobStorage&& value);
658 void Append(Dict&& value);
659 void Append(List&& value);
660
661 // Inserts `value` before `pos` in this list. Returns an iterator to the
662 // inserted value.
663 // TODO(dcheng): Should this provide the same set of overloads that Append()
664 // does?
665 iterator Insert(const_iterator pos, Value&& value);
666
667 // Erases all values equal to `value` from this list.
668 size_t EraseValue(const Value& value);
669
670 // Erases all values for which `predicate` evaluates to true from this list.
671 template <typename Predicate>
672 size_t EraseIf(Predicate predicate) {
673 return base::EraseIf(storage_, predicate);
674 }
675
Scott Haseleye51040782022-03-09 17:32:37676 // Serializes to a string for logging and debug purposes.
677 std::string DebugString() const;
678
Daniel Chengb5862bc2022-06-09 17:04:06679#if BUILDFLAG(ENABLE_BASE_TRACING)
680 // Write this object into a trace.
681 void WriteIntoTrace(perfetto::TracedValue) const;
682#endif // BUILDFLAG(ENABLE_BASE_TRACING)
683
Daniel Chenga367fe52022-02-15 18:08:48684 private:
685 BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
686 BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
687 BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
688 BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
689 BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
690 BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);
691
692 // For legacy access to the internal storage type.
693 friend Value;
694
695 explicit List(const std::vector<Value>& storage);
696
697 std::vector<Value> storage_;
698 };
jdoerriee03e80f2017-02-15 08:42:14699
Daniel Cheng619653b2022-02-17 18:33:12700 // ===== DEPRECATED methods that require `type() == Type::LIST` =====
701
Jan Wilken Dörrie69a65a3a2020-01-16 15:03:30702 // Returns the Values in a list as a view. The mutable overload allows for
703 // modification of the underlying values, but does not allow changing the
Matt Menke5f2ff7b2022-06-30 16:49:27704 // structure of the list.
Daniel Cheng619653b2022-02-17 18:33:12705 //
706 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
707 // `GetList()` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06708 DeprecatedListView GetListDeprecated();
709 DeprecatedConstListView GetListDeprecated() const;
jdoerrie2b7d0fcd2017-04-19 07:15:38710
Gabriel Charetteb49d73a2021-05-05 20:05:59711 // Appends `value` to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:12712 //
713 // DEPRECATED: prefer `Value::List::Append()`.
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24714 void Append(Value&& value);
Daniel Cheng619653b2022-02-17 18:33:12715 // DEPRECATED: prefer `Value::List::Append()`.
716 void Append(bool value);
717 template <typename T>
718 void Append(const T* ptr) = delete;
719 // DEPRECATED: prefer `Value::List::Append()`.
720 void Append(int value);
721 // DEPRECATED: prefer `Value::List::Append()`.
722 void Append(double value);
723 // DEPRECATED: prefer `Value::List::Append()`.
724 void Append(StringPiece value);
725 // DEPRECATED: prefer `Value::List::Append()`.
726 void Append(StringPiece16 value);
727 // DEPRECATED: prefer `Value::List::Append()`.
728 void Append(const char* value);
729 // DEPRECATED: prefer `Value::List::Append()`.
Daniel Cheng619653b2022-02-17 18:33:12730 void Append(std::string&& value);
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24731
Gabriel Charetteb49d73a2021-05-05 20:05:59732 // Erases the Value pointed to by `iter`. Returns false if `iter` is out of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05733 // bounds.
Daniel Cheng619653b2022-02-17 18:33:12734 //
735 // DEPRECATED: prefer `Value::List::erase(iter)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05736 bool EraseListIter(CheckedContiguousConstIterator<Value> iter);
737
Gabriel Charetteb49d73a2021-05-05 20:05:59738 // Erases all Values that compare equal to `val`. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05739 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12740 //
741 // DEPRECATED: prefer `Value::List::EraseValue(val)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05742 size_t EraseListValue(const Value& val);
743
Gabriel Charetteb49d73a2021-05-05 20:05:59744 // Erases all Values for which `pred` returns true. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05745 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12746 //
747 // DEPRECATED: prefer `Value::List::EraseIf(pred)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05748 template <typename Predicate>
749 size_t EraseListValueIf(Predicate pred) {
Jan Wilken Dörrie79d022142020-08-19 18:18:32750 return base::EraseIf(list(), pred);
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05751 }
752
Jan Wilken Dörrie02577a22019-12-04 14:27:39753 // Erases all Values from the list.
Daniel Cheng619653b2022-02-17 18:33:12754 //
755 // DEPRECATED: prefer `Value::List::clear()`.
Jan Wilken Dörrie02577a22019-12-04 14:27:39756 void ClearList();
757
Daniel Cheng619653b2022-02-17 18:33:12758 // ===== DEPRECATED methods that require `type() == Type::DICT` =====
759
Gabriel Charetteb49d73a2021-05-05 20:05:59760 // `FindKey` looks up `key` in the underlying dictionary. If found, it returns
jdoerrie78ab7a22017-08-17 19:04:45761 // a pointer to the element. Otherwise it returns nullptr.
jdoerrie78ab7a22017-08-17 19:04:45762 //
Daniel Cheng619653b2022-02-17 18:33:12763 // DEPRECATED: prefer `Value::Dict::Find()`.
jdoerrie78ab7a22017-08-17 19:04:45764 Value* FindKey(StringPiece key);
765 const Value* FindKey(StringPiece key) const;
jdoerrie44efa9d2017-07-14 14:47:20766
Gabriel Charetteb49d73a2021-05-05 20:05:59767 // `FindKeyOfType` is similar to `FindKey`, but it also requires the found
768 // value to have type `type`. If no type is found, or the found value is of a
jdoerrie78ab7a22017-08-17 19:04:45769 // different type nullptr is returned.
jdoerrie78ab7a22017-08-17 19:04:45770 //
Daniel Cheng619653b2022-02-17 18:33:12771 // DEPRECATED: prefer `Value::Dict::FindBool()`, `Value::Dict::FindInt()`, et
772 // cetera.
jdoerrie78ab7a22017-08-17 19:04:45773 Value* FindKeyOfType(StringPiece key, Type type);
774 const Value* FindKeyOfType(StringPiece key, Type type) const;
jdoerrie44efa9d2017-07-14 14:47:20775
Daniel Cheng619653b2022-02-17 18:33:12776 // These are convenience forms of `FindKey`. They return `absl::nullopt` or
777 // `nullptr` if the value is not found or doesn't have the type specified in
778 // the function's name.
779 //
780 // DEPRECATED: prefer `Value::Dict::FindBool()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39781 absl::optional<bool> FindBoolKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12782 // DEPRECATED: prefer `Value::Dict::FindInt()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39783 absl::optional<int> FindIntKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12784 // Returns a non-null value for both `Value::Type::DOUBLE` and
785 // `Value::Type::INT`, converting the latter to a double.
786 //
787 // DEPRECATED: prefer `Value::Dict::FindDouble()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39788 absl::optional<double> FindDoubleKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12789 // DEPRECATED: prefer `Value::Dict::FindString()`.
Vladislav Kuzkokov193a2ba2019-01-08 11:33:16790 const std::string* FindStringKey(StringPiece key) const;
Dominic Battre08cbe972019-07-31 03:57:19791 std::string* FindStringKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12792 // DEPRECATED: prefer `Value::Dict::FindBlob()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06793 const BlobStorage* FindBlobKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12794 // DEPRECATED: prefer `Value::Dict::FindDict()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06795 const Value* FindDictKey(StringPiece key) const;
796 Value* FindDictKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12797 // DEPRECATED: prefer `Value::Dict::FindList()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06798 const Value* FindListKey(StringPiece key) const;
799 Value* FindListKey(StringPiece key);
800
Gabriel Charetteb49d73a2021-05-05 20:05:59801 // `SetKey` looks up `key` in the underlying dictionary and sets the mapped
802 // value to `value`. If `key` could not be found, a new element is inserted.
jdoerrie78ab7a22017-08-17 19:04:45803 // A pointer to the modified item is returned.
jdoerrie78ab7a22017-08-17 19:04:45804 //
Daniel Cheng619653b2022-02-17 18:33:12805 // Note: Prefer `Set<Type>Key()` if the input is not already a `Value`.
806 //
807 // DEPRECATED: Prefer `Value::Dict::Set()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16808 Value* SetKey(StringPiece key, Value&& value);
jdoerrie44efa9d2017-07-14 14:47:20809
Gabriel Charetteb49d73a2021-05-05 20:05:59810 // `Set`Type>Key` looks up `key` in the underlying dictionary and associates a
811 // corresponding Value() constructed from the second parameter. Compared to
812 // `SetKey()`, this avoids un-necessary temporary `Value()` creation, as well
David 'Digit' Turnere169e6c2019-03-28 22:06:29813 // ambiguities in the value type.
Daniel Cheng619653b2022-02-17 18:33:12814 //
815 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29816 Value* SetBoolKey(StringPiece key, bool val);
Daniel Cheng619653b2022-02-17 18:33:12817 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29818 Value* SetIntKey(StringPiece key, int val);
Daniel Cheng619653b2022-02-17 18:33:12819 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29820 Value* SetDoubleKey(StringPiece key, double val);
Daniel Cheng619653b2022-02-17 18:33:12821 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29822 Value* SetStringKey(StringPiece key, StringPiece val);
Daniel Cheng619653b2022-02-17 18:33:12823 // DEPRECATED: Prefer `Value::Dict::Set()`.
Jan Wilken Dörrie293405a2020-05-12 19:45:11824 Value* SetStringKey(StringPiece key, StringPiece16 val);
Daniel Cheng619653b2022-02-17 18:33:12825 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29826 Value* SetStringKey(StringPiece key, const char* val);
Daniel Cheng619653b2022-02-17 18:33:12827 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29828 Value* SetStringKey(StringPiece key, std::string&& val);
David 'Digit' Turnere169e6c2019-03-28 22:06:29829
Gabriel Charetteb49d73a2021-05-05 20:05:59830 // This attempts to remove the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46831 // failure, e.g. the key does not exist, false is returned and the underlying
Gabriel Charetteb49d73a2021-05-05 20:05:59832 // dictionary is not changed. In case of success, `key` is deleted from the
jdoerriec209c7d2019-04-05 09:51:46833 // dictionary and the method returns true.
jdoerrie64783162017-09-04 16:33:32834 //
Daniel Cheng619653b2022-02-17 18:33:12835 // Deprecated: Prefer `Value::Dict::Remove()`.
jdoerrie64783162017-09-04 16:33:32836 bool RemoveKey(StringPiece key);
837
Gabriel Charetteb49d73a2021-05-05 20:05:59838 // This attempts to extract the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46839 // failure, e.g. the key does not exist, nullopt is returned and the
Gabriel Charetteb49d73a2021-05-05 20:05:59840 // underlying dictionary is not changed. In case of success, `key` is deleted
jdoerriec209c7d2019-04-05 09:51:46841 // from the dictionary and the method returns the extracted Value.
jdoerriec209c7d2019-04-05 09:51:46842 //
Daniel Cheng619653b2022-02-17 18:33:12843 // DEPRECATED: Prefer `Value::Dict::Extract()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39844 absl::optional<Value> ExtractKey(StringPiece key);
jdoerriec209c7d2019-04-05 09:51:46845
Brett Wilsond16cf4ee2017-08-03 00:08:27846 // Searches a hierarchy of dictionary values for a given value. If a path
847 // of dictionaries exist, returns the item at that path. If any of the path
848 // components do not exist or if any but the last path components are not
Daniel Cheng619653b2022-02-17 18:33:12849 // dictionaries, returns nullptr. The type of the leaf Value is not checked.
Brett Wilsond16cf4ee2017-08-03 00:08:27850 //
David 'Digit' Turner43ce6492019-04-04 16:04:44851 // This version takes a StringPiece for the path, using dots as separators.
Daniel Cheng619653b2022-02-17 18:33:12852 //
853 // DEPRECATED: Prefer `Value::Dict::FindByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44854 Value* FindPath(StringPiece path);
855 const Value* FindPath(StringPiece path) const;
856
857 // There are also deprecated versions that take the path parameter
858 // as either a std::initializer_list<StringPiece> or a
859 // span<const StringPiece>. The latter is useful to use a
860 // std::vector<std::string> as a parameter but creates huge dynamic
jdoerriec209c7d2019-04-05 09:51:46861 // allocations and should be avoided!
Gabriel Charetteb49d73a2021-05-05 20:05:59862 // Note: If there is only one component in the path, use `FindKey()` instead.
jdoerriec209c7d2019-04-05 09:51:46863 //
David 'Digit' Turner43ce6492019-04-04 16:04:44864 // Example:
jdoerriecd022242017-08-23 08:38:27865 // std::vector<StringPiece> components = ...
866 // auto* found = FindPath(components);
Daniel Cheng619653b2022-02-17 18:33:12867 //
868 // DEPRECATED: These are not common, and there is no currently planned
869 // replacement.
jdoerriecd022242017-08-23 08:38:27870 Value* FindPath(std::initializer_list<StringPiece> path);
871 Value* FindPath(span<const StringPiece> path);
872 const Value* FindPath(std::initializer_list<StringPiece> path) const;
873 const Value* FindPath(span<const StringPiece> path) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27874
Lei Zhange0fc6f02017-10-27 00:27:23875 // Like FindPath() but will only return the value if the leaf Value type
Brett Wilsond16cf4ee2017-08-03 00:08:27876 // matches the given type. Will return nullptr otherwise.
Gabriel Charetteb49d73a2021-05-05 20:05:59877 // Note: Prefer `Find<Type>Path()` for simple values.
Lei Zhange0fc6f02017-10-27 00:27:23878 //
Gabriel Charetteb49d73a2021-05-05 20:05:59879 // Note: If there is only one component in the path, use `FindKeyOfType()`
David 'Digit' Turner43ce6492019-04-04 16:04:44880 // instead for slightly better performance.
Daniel Cheng619653b2022-02-17 18:33:12881 //
882 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`,
883 // `Value::Dict::FindIntByDottedPath()`, et cetera.
David 'Digit' Turner43ce6492019-04-04 16:04:44884 Value* FindPathOfType(StringPiece path, Type type);
885 const Value* FindPathOfType(StringPiece path, Type type) const;
886
887 // Convenience accessors used when the expected type of a value is known.
888 // Similar to Find<Type>Key() but accepts paths instead of keys.
Daniel Cheng619653b2022-02-17 18:33:12889 //
890 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`, or
891 // `Value::Dict::FindBool()` if the path only has one component, i.e. has no
892 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39893 absl::optional<bool> FindBoolPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12894 // DEPRECATED: Use `Value::Dict::FindIntByDottedPath()`, or
895 // `Value::Dict::FindInt()` if the path only has one component, i.e. has no
896 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39897 absl::optional<int> FindIntPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12898 // DEPRECATED: Use `Value::Dict::FindDoubleByDottedPath()`, or
899 // `Value::Dict::FindDouble()` if the path only has one component, i.e. has no
900 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39901 absl::optional<double> FindDoublePath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12902 // DEPRECATED: Use `Value::Dict::FindStringByDottedPath()`, or
903 // `Value::Dict::FindString()` if the path only has one component, i.e. has no
904 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44905 const std::string* FindStringPath(StringPiece path) const;
Dominic Battre08cbe972019-07-31 03:57:19906 std::string* FindStringPath(StringPiece path);
Daniel Cheng619653b2022-02-17 18:33:12907 // DEPRECATED: Use `Value::Dict::FindDictByDottedPath()`, or
908 // `Value::Dict::FindDict()` if the path only has one component, i.e. has no
909 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44910 Value* FindDictPath(StringPiece path);
911 const Value* FindDictPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12912 // DEPRECATED: Use `Value::Dict::FindListByDottedPath()`, or
913 // `Value::Dict::FindList()` if the path only has one component, i.e. has no
914 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44915 Value* FindListPath(StringPiece path);
916 const Value* FindListPath(StringPiece path) const;
917
918 // The following forms are deprecated too, use the ones that take the path
919 // as a single StringPiece instead.
Daniel Cheng619653b2022-02-17 18:33:12920 //
921 // DEPRECATED: These are not common, and there is no currently planned
922 // replacement.
jdoerriecd022242017-08-23 08:38:27923 Value* FindPathOfType(std::initializer_list<StringPiece> path, Type type);
924 Value* FindPathOfType(span<const StringPiece> path, Type type);
925 const Value* FindPathOfType(std::initializer_list<StringPiece> path,
Brett Wilsond16cf4ee2017-08-03 00:08:27926 Type type) const;
jdoerriecd022242017-08-23 08:38:27927 const Value* FindPathOfType(span<const StringPiece> path, Type type) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27928
929 // Sets the given path, expanding and creating dictionary keys as necessary.
930 //
jdoerrie64783162017-09-04 16:33:32931 // If the current value is not a dictionary, the function returns nullptr. If
932 // path components do not exist, they will be created. If any but the last
933 // components matches a value that is not a dictionary, the function will fail
934 // (it will not overwrite the value) and return nullptr. The last path
935 // component will be unconditionally overwritten if it exists, and created if
936 // it doesn't.
Brett Wilsond16cf4ee2017-08-03 00:08:27937 //
Gabriel Charetteb49d73a2021-05-05 20:05:59938 // Note: If there is only one component in the path, use `SetKey()` instead.
939 // Note: Using `Set<Type>Path()` might be more convenient and efficient.
Daniel Cheng619653b2022-02-17 18:33:12940 //
941 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44942 Value* SetPath(StringPiece path, Value&& value);
943
944 // These setters are more convenient and efficient than the corresponding
945 // SetPath(...) call.
Daniel Cheng619653b2022-02-17 18:33:12946 //
947 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44948 Value* SetBoolPath(StringPiece path, bool value);
Daniel Cheng619653b2022-02-17 18:33:12949 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44950 Value* SetIntPath(StringPiece path, int value);
Daniel Cheng619653b2022-02-17 18:33:12951 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44952 Value* SetDoublePath(StringPiece path, double value);
Daniel Cheng619653b2022-02-17 18:33:12953 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44954 Value* SetStringPath(StringPiece path, StringPiece value);
Daniel Cheng619653b2022-02-17 18:33:12955 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44956 Value* SetStringPath(StringPiece path, const char* value);
Daniel Cheng619653b2022-02-17 18:33:12957 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44958 Value* SetStringPath(StringPiece path, std::string&& value);
Daniel Cheng619653b2022-02-17 18:33:12959 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44960 Value* SetStringPath(StringPiece path, StringPiece16 value);
961
Daniel Cheng619653b2022-02-17 18:33:12962 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16963 Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
964 Value* SetPath(span<const StringPiece> path, Value&& value);
Brett Wilsond16cf4ee2017-08-03 00:08:27965
jdoerrie64783162017-09-04 16:33:32966 // Tries to remove a Value at the given path.
967 //
jdoerriec209c7d2019-04-05 09:51:46968 // If the current value is not a dictionary or any path component does not
jdoerrie64783162017-09-04 16:33:32969 // exist, this operation fails, leaves underlying Values untouched and returns
Gabriel Charetteb49d73a2021-05-05 20:05:59970 // `false`. In case intermediate dictionaries become empty as a result of this
jdoerrie64783162017-09-04 16:33:32971 // path removal, they will be removed as well.
Song Fangzhen09e06912021-07-21 15:01:28972 // Note: If there is only one component in the path, use `RemoveKey()`
Gabriel Charetteb49d73a2021-05-05 20:05:59973 // instead.
jdoerrie64783162017-09-04 16:33:32974 //
Daniel Cheng619653b2022-02-17 18:33:12975 // DEPRECATED: Use `Value::Dict::RemoveByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44976 bool RemovePath(StringPiece path);
977
jdoerriec209c7d2019-04-05 09:51:46978 // Tries to extract a Value at the given path.
979 //
980 // If the current value is not a dictionary or any path component does not
981 // exist, this operation fails, leaves underlying Values untouched and returns
982 // nullopt. In case intermediate dictionaries become empty as a result of this
983 // path removal, they will be removed as well. Returns the extracted value on
984 // success.
Gabriel Charetteb49d73a2021-05-05 20:05:59985 // Note: If there is only one component in the path, use `ExtractKey()`
986 // instead.
jdoerriec209c7d2019-04-05 09:51:46987 //
Daniel Cheng619653b2022-02-17 18:33:12988 // DEPRECATED: Use `Value::Dict::ExtractByDottedPath()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39989 absl::optional<Value> ExtractPath(StringPiece path);
jdoerriec209c7d2019-04-05 09:51:46990
jdoerrie78ab7a22017-08-17 19:04:45991 using dict_iterator_proxy = detail::dict_iterator_proxy;
992 using const_dict_iterator_proxy = detail::const_dict_iterator_proxy;
jdoerrie44efa9d2017-07-14 14:47:20993
Gabriel Charetteb49d73a2021-05-05 20:05:59994 // `DictItems` returns a proxy object that exposes iterators to the underlying
jdoerrie44efa9d2017-07-14 14:47:20995 // dictionary. These are intended for iteration over all items in the
996 // dictionary and are compatible with for-each loops and standard library
997 // algorithms.
David Van Cleve373381d2020-01-07 18:16:13998 //
Gabriel Charetteb49d73a2021-05-05 20:05:59999 // Unlike with std::map, a range-for over the non-const version of
1000 // `DictItems()` will range over items of type
1001 // `pair<const std::string&, Value&>`, so code of the form
David Van Cleve373381d2020-01-07 18:16:131002 // for (auto kv : my_value.DictItems())
1003 // Mutate(kv.second);
Gabriel Charetteb49d73a2021-05-05 20:05:591004 // will actually alter `my_value` in place (if it isn't const).
David Van Cleve373381d2020-01-07 18:16:131005 //
Daniel Cheng619653b2022-02-17 18:33:121006 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1007 // instead.
jdoerrie44efa9d2017-07-14 14:47:201008 dict_iterator_proxy DictItems();
1009 const_dict_iterator_proxy DictItems() const;
1010
Daniel Cheng619653b2022-02-17 18:33:121011 // DEPRECATED: prefer `Value::Dict::size()`.
Lei Zhange823c512018-05-07 20:27:301012 size_t DictSize() const;
Daniel Cheng619653b2022-02-17 18:33:121013
1014 // DEPRECATED: prefer `Value::Dict::empty()`.
Lei Zhange823c512018-05-07 20:27:301015 bool DictEmpty() const;
Daniel Cheng619653b2022-02-17 18:33:121016
1017 // DEPRECATED: prefer `Value::Dict::clear()`.
Panos Astithas0532a862020-10-29 04:15:071018 void DictClear();
Lei Zhange823c512018-05-07 20:27:301019
Gabriel Charetteb49d73a2021-05-05 20:05:591020 // Merge `dictionary` into this value. This is done recursively, i.e. any
jdoerriec1091282018-08-01 17:28:121021 // sub-dictionaries will be merged as well. In case of key collisions, the
1022 // passed in dictionary takes precedence and data already present will be
Gabriel Charetteb49d73a2021-05-05 20:05:591023 // replaced. Values within `dictionary` are deep-copied, so `dictionary` may
jdoerriec1091282018-08-01 17:28:121024 // be freed any time after this call.
Gabriel Charetteb49d73a2021-05-05 20:05:591025 // Note: This requires that `type()` and `dictionary->type()` is
Daniel Chenga367fe52022-02-15 18:08:481026 // Type::DICT.
Daniel Cheng619653b2022-02-17 18:33:121027 //
1028 // DEPRECATED: prefer `Value::Dict::Merge()`.
jdoerriec1091282018-08-01 17:28:121029 void MergeDictionary(const Value* dictionary);
1030
[email protected]2f03f532013-07-17 08:43:331031 // These methods allow the convenient retrieval of the contents of the Value.
1032 // If the current object can be converted into the given type, the value is
Gabriel Charetteb49d73a2021-05-05 20:05:591033 // returned through the `out_value` parameter and true is returned;
1034 // otherwise, false is returned and `out_value` is unchanged.
lukaszad1485da72016-11-01 21:49:461035 // DictionaryValue::From is the equivalent for std::unique_ptr conversions.
Daniel Cheng619653b2022-02-17 18:33:121036 //
1037 // DEPRECATED: prefer direct use `base::Value::Dict` where possible, or
1038 // `GetIfDict()` otherwise.
jdoerrie8e945542017-02-17 13:54:491039 bool GetAsDictionary(DictionaryValue** out_value);
1040 bool GetAsDictionary(const DictionaryValue** out_value) const;
[email protected]2f03f532013-07-17 08:43:331041 // Note: Do not add more types. See the file-level comment above for why.
initial.commitd7cae122008-07-26 21:49:381042
1043 // This creates a deep copy of the entire Value tree, and returns a pointer
jdoerrie05eb3162017-02-01 10:36:561044 // to the copy. The caller gets ownership of the copy, of course.
[email protected]16f47e082011-01-18 02:16:591045 // Subclasses return their own type directly in their overrides;
1046 // this works because C++ supports covariant return types.
jdoerriee964d9a2017-04-05 06:44:171047 // TODO(crbug.com/646113): Delete this and migrate callsites.
Daniel Cheng619653b2022-02-17 18:33:121048 //
1049 // DEPRECATED: prefer `Value::Clone()`.
dcheng093de9b2016-04-04 21:25:511050 std::unique_ptr<Value> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381051
jdoerrie5c1cee112017-03-28 17:52:001052 // Comparison operators so that Values can easily be used with standard
1053 // library algorithms and associative containers.
1054 BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
1055 BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs);
1056 BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs);
1057 BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs);
1058 BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
1059 BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);
1060
Daniel Cheng0b0b6752022-05-25 02:59:481061 BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs);
1062 friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; }
1063 friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); }
1064 friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); }
Daniel Cheng6b621cf2022-06-02 02:42:021065 template <typename T>
1066 friend bool operator==(const Value& lhs, const T* rhs) = delete;
1067 template <typename T>
1068 friend bool operator==(const T* lhs, const Value& rhs) = delete;
1069 template <typename T>
1070 friend bool operator!=(const Value& lhs, const T* rhs) = delete;
1071 template <typename T>
1072 friend bool operator!=(const T* lhs, const Value& rhs) = delete;
Daniel Cheng0b0b6752022-05-25 02:59:481073 BASE_EXPORT friend bool operator==(const Value& lhs, int rhs);
1074 friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; }
1075 friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); }
1076 friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); }
1077 BASE_EXPORT friend bool operator==(const Value& lhs, double rhs);
1078 friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; }
1079 friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); }
1080 friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); }
Daniel Cheng6b621cf2022-06-02 02:42:021081 // Note: StringPiece16 overload intentionally omitted: Value internally stores
1082 // strings as UTF-8. While it is possible to implement a comparison operator
1083 // that would not require first creating a new UTF-8 string from the UTF-16
1084 // string argument, it is simpler to just not implement it at all for a rare
1085 // use case.
Daniel Cheng0b0b6752022-05-25 02:59:481086 BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs);
1087 friend bool operator==(StringPiece lhs, const Value& rhs) {
1088 return rhs == lhs;
1089 }
1090 friend bool operator!=(const Value& lhs, StringPiece rhs) {
1091 return !(lhs == rhs);
1092 }
1093 friend bool operator!=(StringPiece lhs, const Value& rhs) {
1094 return !(lhs == rhs);
1095 }
Daniel Cheng6b621cf2022-06-02 02:42:021096 friend bool operator==(const Value& lhs, const char* rhs) {
1097 return lhs == StringPiece(rhs);
1098 }
1099 friend bool operator==(const char* lhs, const Value& rhs) {
1100 return rhs == lhs;
1101 }
1102 friend bool operator!=(const Value& lhs, const char* rhs) {
1103 return !(lhs == rhs);
1104 }
1105 friend bool operator!=(const char* lhs, const Value& rhs) {
1106 return !(lhs == rhs);
1107 }
1108 friend bool operator==(const Value& lhs, const std::string& rhs) {
1109 return lhs == StringPiece(rhs);
1110 }
1111 friend bool operator==(const std::string& lhs, const Value& rhs) {
1112 return rhs == lhs;
1113 }
1114 friend bool operator!=(const Value& lhs, const std::string& rhs) {
1115 return !(lhs == rhs);
1116 }
1117 friend bool operator!=(const std::string& lhs, const Value& rhs) {
1118 return !(lhs == rhs);
1119 }
Daniel Cheng0b0b6752022-05-25 02:59:481120 // Note: Blob support intentionally omitted as an experiment for potentially
1121 // wholly removing Blob support from Value itself in the future.
1122 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs);
1123 friend bool operator==(const Value::Dict& lhs, const Value& rhs) {
1124 return rhs == lhs;
1125 }
1126 friend bool operator!=(const Value& lhs, const Value::Dict& rhs) {
1127 return !(lhs == rhs);
1128 }
1129 friend bool operator!=(const Value::Dict& lhs, const Value& rhs) {
1130 return !(lhs == rhs);
1131 }
1132 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs);
1133 friend bool operator==(const Value::List& lhs, const Value& rhs) {
1134 return rhs == lhs;
1135 }
1136 friend bool operator!=(const Value& lhs, const Value::List& rhs) {
1137 return !(lhs == rhs);
1138 }
1139 friend bool operator!=(const Value::List& lhs, const Value& rhs) {
1140 return !(lhs == rhs);
1141 }
1142
Eric Secklerf6c544f2020-06-02 10:49:211143 // Estimates dynamic memory usage. Requires tracing support
1144 // (enable_base_tracing gn flag), otherwise always returns 0. See
1145 // base/trace_event/memory_usage_estimator.h for more info.
Alexander Yashkinab504e72017-11-30 11:54:451146 size_t EstimateMemoryUsage() const;
1147
Alan Cutter2dd83032020-12-08 21:55:001148 // Serializes to a string for logging and debug purposes.
1149 std::string DebugString() const;
1150
Peter Kotwicz83a231372021-04-13 17:42:121151#if BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211152 // Write this object into a trace.
Alexander Timinbebb2002021-04-20 15:42:241153 void WriteIntoTrace(perfetto::TracedValue) const;
Peter Kotwicz83a231372021-04-13 17:42:121154#endif // BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211155
Daniel Cheng8ac305b2022-02-17 00:05:111156 template <typename Visitor>
1157 auto Visit(Visitor&& visitor) const {
1158 return absl::visit(std::forward<Visitor>(visitor), data_);
1159 }
1160
jdoerrie8e945542017-02-17 13:54:491161 protected:
Matt Menke06842489d2022-07-22 00:04:331162 // TODO(https://crbug.com/1187091): Once deprecated list methods and ListView
1163 // have been removed, make this a private member of List.
1164 using ListStorage = DeprecatedListStorage;
1165
Jan Wilken Dörrie79d022142020-08-19 18:18:321166 // Checked convenience accessors for dict and list.
Daniel Chenga367fe52022-02-15 18:08:481167 const LegacyDictStorage& dict() const { return GetDict().storage_; }
1168 LegacyDictStorage& dict() { return GetDict().storage_; }
1169 const ListStorage& list() const { return GetList().storage_; }
1170 ListStorage& list() { return GetList().storage_; }
Jan Wilken Dörrie79d022142020-08-19 18:18:321171
Jan Wilken Dörrief961a372020-11-02 20:30:341172 // Internal constructors, allowing the simplify the implementation of Clone().
1173 explicit Value(const LegacyDictStorage& storage);
1174 explicit Value(LegacyDictStorage&& storage) noexcept;
1175
Jan Wilken Dörrie79d022142020-08-19 18:18:321176 private:
Daniel Cheng8ac305b2022-02-17 00:05:111177 // For access to DoubleStorage.
1178 friend class ValueView;
1179
David 'Digit' Turner2f287312019-04-03 14:32:091180 // Special case for doubles, which are aligned to 8 bytes on some
1181 // 32-bit architectures. In this case, a simple declaration as a
1182 // double member would make the whole union 8 byte-aligned, which
1183 // would also force 4 bytes of wasted padding space before it in
1184 // the Value layout.
David 'Digit' Turner806dedb82019-03-06 17:43:111185 //
David 'Digit' Turner2f287312019-04-03 14:32:091186 // To override this, store the value as an array of 32-bit integers, and
1187 // perform the appropriate bit casts when reading / writing to it.
Daniel Cheng6b621cf2022-06-02 02:42:021188 class BASE_EXPORT DoubleStorage {
Daniel Cheng782d2ba32022-02-16 19:40:291189 public:
1190 explicit DoubleStorage(double v);
1191 DoubleStorage(const DoubleStorage&) = default;
1192 DoubleStorage& operator=(const DoubleStorage&) = default;
1193
Daniel Cheng8ac305b2022-02-17 00:05:111194 // Provide an implicit conversion to double to simplify the use of visitors
1195 // with `Value::Visit()`. Otherwise, visitors would need a branch for
1196 // handling `DoubleStorage` like:
1197 //
1198 // value.Visit([] (const auto& member) {
1199 // using T = std::decay_t<decltype(member)>;
1200 // if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
1201 // SomeFunction(double{member});
1202 // } else {
1203 // SomeFunction(member);
1204 // }
1205 // });
Peter Kastingcc88ac052022-05-03 09:58:011206 operator double() const { return base::bit_cast<double>(v_); }
Daniel Cheng782d2ba32022-02-16 19:40:291207
1208 private:
1209 friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111210 return double{lhs} == double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291211 }
1212
1213 friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1214 return !(lhs == rhs);
1215 }
1216
1217 friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111218 return double{lhs} < double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291219 }
1220
1221 friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1222 return rhs < lhs;
1223 }
1224
1225 friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1226 return !(rhs < lhs);
1227 }
1228
1229 friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1230 return !(lhs < rhs);
1231 }
1232
1233 alignas(4) std::array<char, sizeof(double)> v_;
1234 };
David 'Digit' Turner2f287312019-04-03 14:32:091235
Jan Wilken Dörrie79d022142020-08-19 18:18:321236 // Internal constructors, allowing the simplify the implementation of Clone().
1237 explicit Value(absl::monostate);
1238 explicit Value(DoubleStorage storage);
jdoerrie8e945542017-02-17 13:54:491239
Claudio DeSouzab8754a3e2022-07-25 18:08:451240 // A helper for static functions used for cloning a Value or a ValueView.
1241 class CloningHelper;
1242
Jan Wilken Dörrie79d022142020-08-19 18:18:321243 absl::variant<absl::monostate,
1244 bool,
1245 int,
1246 DoubleStorage,
1247 std::string,
1248 BlobStorage,
Daniel Chenga367fe52022-02-15 18:08:481249 Dict,
1250 List>
Jan Wilken Dörrie79d022142020-08-19 18:18:321251 data_;
initial.commitd7cae122008-07-26 21:49:381252};
1253
Li-Yu Yu24e6c7b2022-08-25 04:30:431254// DictAdapterForMigration is an adapter class to help the migration of
1255// base::DictionaryValue to base::Value::Dict.
1256//
1257// DictAdapterForMigration mirrors the API of base::Value::Dict,
1258// and is implicitly constructable from both base::DictionaryValue
1259// and base::Value::Dict. Currently this is read-only, similar to StringPiece.
1260//
1261// To migrate a function that takes a base::DictionaryValue, change the
1262// signature to take DictAdapterForMigration instead, and update the
1263// function body to use the Dict::Value API.
1264// The call sites can be left unchanged and migrated later.
1265//
1266// Note that DictAdapterForMigration is intended as a shim to help migrations,
1267// and will go away with base::DictionaryValue.
1268class BASE_EXPORT GSL_POINTER DictAdapterForMigration {
1269 public:
1270 using iterator = detail::dict_iterator;
1271 using const_iterator = detail::const_dict_iterator;
1272
1273 DictAdapterForMigration() = delete;
1274
1275 // NOLINTNEXTLINE(google-explicit-constructor)
1276 DictAdapterForMigration(const Value::Dict&) noexcept;
1277 // NOLINTNEXTLINE(google-explicit-constructor)
1278 DictAdapterForMigration(const DictionaryValue&) noexcept;
1279
1280 bool empty() const;
1281 size_t size() const;
1282
1283 const_iterator begin() const;
1284 const_iterator cbegin() const;
1285 const_iterator end() const;
1286 const_iterator cend() const;
1287
1288 bool contains(base::StringPiece key) const;
1289
1290 Value::Dict Clone() const;
1291
1292 const Value* Find(StringPiece key) const;
1293 absl::optional<bool> FindBool(StringPiece key) const;
1294 absl::optional<int> FindInt(StringPiece key) const;
1295 absl::optional<double> FindDouble(StringPiece key) const;
1296 const std::string* FindString(StringPiece key) const;
1297 const Value::BlobStorage* FindBlob(StringPiece key) const;
1298 const Value::Dict* FindDict(StringPiece key) const;
1299 const Value::List* FindList(StringPiece key) const;
1300
1301 const Value* FindByDottedPath(StringPiece path) const;
1302
1303 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
1304 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
1305 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
1306 const std::string* FindStringByDottedPath(StringPiece path) const;
1307 const Value::BlobStorage* FindBlobByDottedPath(StringPiece path) const;
1308 const Value::Dict* FindDictByDottedPath(StringPiece path) const;
1309 const Value::List* FindListByDottedPath(StringPiece path) const;
1310
1311 std::string DebugString() const;
1312
1313#if BUILDFLAG(ENABLE_BASE_TRACING)
1314 void WriteIntoTrace(perfetto::TracedValue) const;
1315#endif // BUILDFLAG(ENABLE_BASE_TRACING)
1316
1317 const Value::Dict& dict_for_test() const;
1318
1319 private:
1320 const Value::Dict& dict_;
1321};
1322
[email protected]9e4cda7332010-07-31 04:56:141323// DictionaryValue provides a key-value dictionary with (optional) "path"
1324// parsing for recursive access; see the comment at the top of the file. Keys
Gabriel Charetted7c00cbe2021-05-14 20:05:531325// are std::string's and should be UTF-8 encoded.
Daniel Cheng619653b2022-02-17 18:33:121326//
1327// DEPRECATED: prefer `Value::Dict`.
[email protected]0bea7252011-08-05 15:34:001328class BASE_EXPORT DictionaryValue : public Value {
initial.commitd7cae122008-07-26 21:49:381329 public:
Gabriel Charetteb49d73a2021-05-05 20:05:591330 // Returns `value` if it is a dictionary, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511331 static std::unique_ptr<DictionaryValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541332
[email protected]3a3d47472010-07-15 21:03:541333 DictionaryValue();
Jan Wilken Dörrief961a372020-11-02 20:30:341334 explicit DictionaryValue(const LegacyDictStorage& in_dict);
1335 explicit DictionaryValue(LegacyDictStorage&& in_dict) noexcept;
[email protected]5cf906f82011-11-26 01:11:441336
initial.commitd7cae122008-07-26 21:49:381337 // Sets the Value associated with the given path starting from this object.
1338 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1339 // into the next DictionaryValue down. Obviously, "." can't be used
1340 // within a key, but there are no other restrictions on keys.
1341 // If the key at any step of the way doesn't exist, or exists but isn't
1342 // a DictionaryValue, a new DictionaryValue will be created and attached
Gabriel Charetteb49d73a2021-05-05 20:05:591343 // to the path in that location. `in_value` must be non-null.
jdoerrieb94e5422017-04-28 21:52:581344 // Returns a pointer to the inserted value.
Daniel Cheng619653b2022-02-17 18:33:121345 //
1346 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1347 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1348 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581349 Value* Set(StringPiece path, std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381350
1351 // Convenience forms of Set(). These methods will replace any existing
1352 // value at that path, even if it has a different type.
Daniel Cheng619653b2022-02-17 18:33:121353 //
1354 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1355 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1356 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581357 Value* SetBoolean(StringPiece path, bool in_value);
Daniel Cheng619653b2022-02-17 18:33:121358 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1359 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1360 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581361 Value* SetInteger(StringPiece path, int in_value);
Daniel Cheng619653b2022-02-17 18:33:121362 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1363 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1364 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581365 Value* SetString(StringPiece path, StringPiece in_value);
Daniel Cheng619653b2022-02-17 18:33:121366 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1367 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1368 // otherwise.
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571369 Value* SetString(StringPiece path, const std::u16string& in_value);
Daniel Cheng619653b2022-02-17 18:33:121370 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1371 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1372 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581373 ListValue* SetList(StringPiece path, std::unique_ptr<ListValue> in_value);
[email protected]4dad9ad82009-11-25 20:47:521374
1375 // Like Set(), but without special treatment of '.'. This allows e.g. URLs to
1376 // be used as paths.
Daniel Cheng619653b2022-02-17 18:33:121377 //
1378 // DEPRECATED: prefer `Value::Dict::Set()`.
jdoerrieb94e5422017-04-28 21:52:581379 Value* SetWithoutPathExpansion(StringPiece key,
1380 std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381381
1382 // Gets the Value associated with the given path starting from this object.
1383 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1384 // into the next DictionaryValue down. If the path can be resolved
1385 // successfully, the value for the last key in the path will be returned
Gabriel Charetteb49d73a2021-05-05 20:05:591386 // through the `out_value` parameter, and the function will return true.
1387 // Otherwise, it will return false and `out_value` will be untouched.
initial.commitd7cae122008-07-26 21:49:381388 // Note that the dictionary always owns the value that's returned.
Gabriel Charetteb49d73a2021-05-05 20:05:591389 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121390 //
1391 // DEPRECATED: prefer `Value::Dict::Find()` (if the path only has one
1392 // component, i.e. has no dots), or `Value::Dict::FindByDottedPath()`
1393 // otherwise.
asvitkinedbd26533e2015-06-23 18:22:521394 bool Get(StringPiece path, const Value** out_value) const;
1395 bool Get(StringPiece path, Value** out_value);
initial.commitd7cae122008-07-26 21:49:381396
Gabriel Charetteb49d73a2021-05-05 20:05:591397 // These are convenience forms of `Get()`. The value will be retrieved
initial.commitd7cae122008-07-26 21:49:381398 // and the return value will be true if the path is valid and the value at
1399 // the end of the path can be returned in the form specified.
Gabriel Charetteb49d73a2021-05-05 20:05:591400 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121401 //
1402 // DEPRECATED: prefer `Value::Dict::FindInt()` (if the path only has one
1403 // component, i.e. has no dots), or `Value::Dict::FindIntByDottedPath()`
1404 // otherwise.
dcheng16d6f532016-08-25 16:07:111405 bool GetInteger(StringPiece path, int* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121406 // DEPRECATED: prefer `Value::Dict::FindString()` (if the path only has one
1407 // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
1408 // otherwise.
dcheng16d6f532016-08-25 16:07:111409 bool GetString(StringPiece path, std::string* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121410 // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
1411 // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
1412 // otherwise.
Jan Wilken Dörrie79d022142020-08-19 18:18:321413 bool GetDictionary(StringPiece path, const DictionaryValue** out_value) const;
asvitkinedbd26533e2015-06-23 18:22:521414 bool GetDictionary(StringPiece path, DictionaryValue** out_value);
Daniel Cheng619653b2022-02-17 18:33:121415 // DEPRECATED: prefer `Value::Dict::FindList()` (if the path only has one
1416 // component, i.e. has no dots), or `Value::Dict::FindListByDottedPath()`
1417 // otherwise.
dcheng16d6f532016-08-25 16:07:111418 bool GetList(StringPiece path, const ListValue** out_value) const;
1419 bool GetList(StringPiece path, ListValue** out_value);
initial.commitd7cae122008-07-26 21:49:381420
Gabriel Charetteb49d73a2021-05-05 20:05:591421 // Swaps contents with the `other` dictionary.
jdoerrie8e945542017-02-17 13:54:491422 void Swap(DictionaryValue* other);
[email protected]ec5263a2011-05-10 09:23:391423
[email protected]32c0e002011-11-08 21:26:411424 // This class provides an iterator over both keys and values in the
1425 // dictionary. It can't be used to modify the dictionary.
Daniel Cheng619653b2022-02-17 18:33:121426 //
1427 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1428 // instead.
[email protected]a34cc092012-08-10 12:45:351429 class BASE_EXPORT Iterator {
[email protected]32c0e002011-11-08 21:26:411430 public:
[email protected]a34cc092012-08-10 12:45:351431 explicit Iterator(const DictionaryValue& target);
vmpstre65942b2016-02-25 00:50:311432 Iterator(const Iterator& other);
[email protected]a8d94b42013-12-10 18:52:221433 ~Iterator();
[email protected]32c0e002011-11-08 21:26:411434
Lei Zhang10fce02f2021-05-14 18:45:081435 bool IsAtEnd() const { return it_ == target_.DictItems().end(); }
[email protected]32c0e002011-11-08 21:26:411436 void Advance() { ++it_; }
1437
1438 const std::string& key() const { return it_->first; }
Lei Zhang10fce02f2021-05-14 18:45:081439 const Value& value() const { return it_->second; }
[email protected]32c0e002011-11-08 21:26:411440
1441 private:
1442 const DictionaryValue& target_;
Lei Zhang10fce02f2021-05-14 18:45:081443 detail::const_dict_iterator it_;
[email protected]32c0e002011-11-08 21:26:411444 };
1445
Daniel Cheng619653b2022-02-17 18:33:121446 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerriee964d9a2017-04-05 06:44:171447 // TODO(crbug.com/646113): Delete this and migrate callsites.
dcheng093de9b2016-04-04 21:25:511448 std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381449};
1450
1451// This type of Value represents a list of other Value values.
Daniel Cheng619653b2022-02-17 18:33:121452//
1453// DEPRECATED: prefer `base::Value::List`.
[email protected]0bea7252011-08-05 15:34:001454class BASE_EXPORT ListValue : public Value {
initial.commitd7cae122008-07-26 21:49:381455 public:
Jan Wilken Dörrie46992f022020-02-20 11:25:471456 using const_iterator = ListView::const_iterator;
1457 using iterator = ListView::iterator;
[email protected]a502bbe72011-01-07 18:06:451458
Gabriel Charetteb49d73a2021-05-05 20:05:591459 // Returns `value` if it is a list, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511460 static std::unique_ptr<ListValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541461
[email protected]3a3d47472010-07-15 21:03:541462 ListValue();
initial.commitd7cae122008-07-26 21:49:381463
initial.commitd7cae122008-07-26 21:49:381464 // Appends a Value to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:121465 // DEPRECATED: prefer `Value::List::Append()`.
1466 using Value::Append;
Daniel Chengedfa5202022-04-15 00:09:591467 // DEPRECATED: prefer `Value::List::Append()`. Provided to simplify
1468 // incremental migration and intentionally only defined on ListValue and not
1469 // Value.
1470 void Append(base::Value::Dict in_dict);
1471 void Append(base::Value::List in_list);
initial.commitd7cae122008-07-26 21:49:381472
Gabriel Charetteb49d73a2021-05-05 20:05:591473 // Swaps contents with the `other` list.
Daniel Cheng619653b2022-02-17 18:33:121474 //
1475 // DEPRECATED: prefer `base::Value::List` + `std::swap()`.
jdoerrie8e945542017-02-17 13:54:491476 void Swap(ListValue* other);
[email protected]8b8e7c92010-08-19 18:05:561477
Daniel Cheng619653b2022-02-17 18:33:121478 // Iteration: Use a range-based for loop over `base::Value::List` directly
1479 // instead.
initial.commitd7cae122008-07-26 21:49:381480};
1481
Daniel Cheng8ac305b2022-02-17 00:05:111482// Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
1483// serialization methods without having to clone the contents and transfer
1484// ownership of the clone to a `Value` wrapper object.
1485//
1486// Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
1487// underlying object that is passed by reference (i.e. `std::string`,
1488// `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
1489// live as long as there is a `ValueView` referencing it.
1490//
1491// While it might be nice to just use the `absl::variant` type directly, the
1492// need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
1493// `std::reference_wrapper` both support implicit construction, but C++ only
1494// allows at most one user-defined conversion in an implicit conversion
1495// sequence. If this adapter and its implicit constructors did not exist,
1496// callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
1497// `Value::List` to a function with a `ValueView` parameter.
1498class BASE_EXPORT GSL_POINTER ValueView {
1499 public:
Daniel Cheng6b621cf2022-06-02 02:42:021500 ValueView() = default;
Daniel Cheng8ac305b2022-02-17 00:05:111501 ValueView(bool value) : data_view_(value) {}
Daniel Cheng6b621cf2022-06-02 02:42:021502 template <typename T>
1503 ValueView(const T*) = delete;
Daniel Cheng8ac305b2022-02-17 00:05:111504 ValueView(int value) : data_view_(value) {}
1505 ValueView(double value)
1506 : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
Daniel Cheng6b621cf2022-06-02 02:42:021507 ValueView(StringPiece value) : data_view_(value) {}
1508 ValueView(const char* value) : ValueView(StringPiece(value)) {}
1509 ValueView(const std::string& value) : ValueView(StringPiece(value)) {}
1510 // Note: UTF-16 is intentionally not supported. ValueView is intended to be a
1511 // low-cost view abstraction, but Value internally represents strings as
1512 // UTF-8, so it would not be possible to implement this without allocating an
1513 // entirely new UTF-8 string.
Daniel Cheng8ac305b2022-02-17 00:05:111514 ValueView(const Value::BlobStorage& value) : data_view_(value) {}
1515 ValueView(const Value::Dict& value) : data_view_(value) {}
1516 ValueView(const Value::List& value) : data_view_(value) {}
1517 ValueView(const Value& value);
1518
Daniel Cheng6b621cf2022-06-02 02:42:021519 // This is the only 'getter' method provided as `ValueView` is not intended
1520 // to be a general replacement of `Value`.
Daniel Cheng8ac305b2022-02-17 00:05:111521 template <typename Visitor>
1522 auto Visit(Visitor&& visitor) const {
1523 return absl::visit(std::forward<Visitor>(visitor), data_view_);
1524 }
1525
Claudio DeSouza75d1f3412022-07-22 21:06:421526 // Returns a clone of the underlying Value.
1527 Value ToValue() const;
1528
Daniel Cheng8ac305b2022-02-17 00:05:111529 private:
1530 using ViewType =
1531 absl::variant<absl::monostate,
1532 bool,
1533 int,
1534 Value::DoubleStorage,
Daniel Cheng6b621cf2022-06-02 02:42:021535 StringPiece,
Daniel Cheng8ac305b2022-02-17 00:05:111536 std::reference_wrapper<const Value::BlobStorage>,
1537 std::reference_wrapper<const Value::Dict>,
1538 std::reference_wrapper<const Value::List>>;
1539
Daniel Cheng6b621cf2022-06-02 02:42:021540 public:
1541 using DoubleStorageForTest = Value::DoubleStorage;
1542 const ViewType& data_view_for_test() const { return data_view_; }
1543
1544 private:
Daniel Cheng8ac305b2022-02-17 00:05:111545 ViewType data_view_;
1546};
1547
prashhir54a994502015-03-05 09:30:571548// This interface is implemented by classes that know how to serialize
1549// Value objects.
[email protected]0bea7252011-08-05 15:34:001550class BASE_EXPORT ValueSerializer {
initial.commitd7cae122008-07-26 21:49:381551 public:
[email protected]3a3d47472010-07-15 21:03:541552 virtual ~ValueSerializer();
[email protected]abb9d0c2008-08-06 15:46:591553
Daniel Cheng8ac305b2022-02-17 00:05:111554 virtual bool Serialize(ValueView root) = 0;
prashhir54a994502015-03-05 09:30:571555};
1556
1557// This interface is implemented by classes that know how to deserialize Value
1558// objects.
1559class BASE_EXPORT ValueDeserializer {
1560 public:
1561 virtual ~ValueDeserializer();
initial.commitd7cae122008-07-26 21:49:381562
1563 // This method deserializes the subclass-specific format into a Value object.
[email protected]b4cebf82008-12-29 19:59:081564 // If the return value is non-NULL, the caller takes ownership of returned
Nigel Tao410788e2020-06-24 07:12:271565 // Value.
1566 //
Gabriel Charetteb49d73a2021-05-05 20:05:591567 // If the return value is nullptr, and if `error_code` is non-nullptr,
1568 // `*error_code` will be set to an integer value representing the underlying
Nigel Tao410788e2020-06-24 07:12:271569 // error. See "enum ErrorCode" below for more detail about the integer value.
1570 //
Gabriel Charetteb49d73a2021-05-05 20:05:591571 // If `error_message` is non-nullptr, it will be filled in with a formatted
[email protected]ba399672010-04-06 15:42:391572 // error message including the location of the error if appropriate.
dcheng093de9b2016-04-04 21:25:511573 virtual std::unique_ptr<Value> Deserialize(int* error_code,
Nigel Tao410788e2020-06-24 07:12:271574 std::string* error_message) = 0;
1575
1576 // The integer-valued error codes form four groups:
1577 // - The value 0 means no error.
1578 // - Values between 1 and 999 inclusive mean an error in the data (i.e.
1579 // content). The bytes being deserialized are not in the right format.
1580 // - Values 1000 and above mean an error in the metadata (i.e. context). The
1581 // file could not be read, the network is down, etc.
1582 // - Negative values are reserved.
Caitlin Fischeraac06dc2021-12-17 00:21:321583 //
1584 // These values are persisted to logs. Entries should not be renumbered and
1585 // numeric values should never be reused.
Nigel Tao410788e2020-06-24 07:12:271586 enum ErrorCode {
1587 kErrorCodeNoError = 0,
1588 // kErrorCodeInvalidFormat is a generic error code for "the data is not in
1589 // the right format". Subclasses of ValueDeserializer may return other
1590 // values for more specific errors.
1591 kErrorCodeInvalidFormat = 1,
1592 // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
1593 // range of metadata errors.
1594 kErrorCodeFirstMetadataError = 1000,
1595 };
1596
Gabriel Charetteb49d73a2021-05-05 20:05:591597 // The `error_code` argument can be one of the ErrorCode values, but it is
Nigel Tao410788e2020-06-24 07:12:271598 // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
1599 // can define their own error code values.
1600 static inline bool ErrorCodeIsDataError(int error_code) {
1601 return (kErrorCodeInvalidFormat <= error_code) &&
1602 (error_code < kErrorCodeFirstMetadataError);
1603 }
initial.commitd7cae122008-07-26 21:49:381604};
1605
Daniel Chenga367fe52022-02-15 18:08:481606// Stream operator so Values can be pretty printed by gtest.
[email protected]e4ef8312012-09-12 03:39:351607BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
Daniel Chenga367fe52022-02-15 18:08:481608BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1609 const Value::Dict& dict);
1610BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1611 const Value::List& list);
[email protected]e4ef8312012-09-12 03:39:351612
Daniel Chenga367fe52022-02-15 18:08:481613// Hints for DictionaryValue and ListValue; otherwise, gtest tends to prefer the
1614// default template implementation over an upcast to Value.
[email protected]ea0ec052013-04-16 09:04:021615BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
[email protected]ea0ec052013-04-16 09:04:021616 const DictionaryValue& value) {
1617 return out << static_cast<const Value&>(value);
1618}
1619
1620BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
1621 const ListValue& value) {
1622 return out << static_cast<const Value&>(value);
1623}
1624
jdoerriedc72ee942016-12-07 15:43:281625// Stream operator so that enum class Types can be used in log statements.
1626BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1627 const Value::Type& type);
1628
[email protected]f3a1c642011-07-12 19:15:031629} // namespace base
1630
[email protected]101d5422008-09-26 20:22:421631#endif // BASE_VALUES_H_