blob: 59d3ccfc3295609a45f4a76fb33e81418510e18e [file] [log] [blame]
[email protected]13502562012-05-09 21:54:271// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]101d5422008-09-26 20:22:425#ifndef BASE_VALUES_H_
6#define BASE_VALUES_H_
initial.commitd7cae122008-07-26 21:49:387
[email protected]c014f2b32013-09-03 23:29:128#include <stddef.h>
avi9b6f42932015-12-26 22:15:149#include <stdint.h>
[email protected]c014f2b32013-09-03 23:29:1210
Daniel Cheng782d2ba32022-02-16 19:40:2911#include <array>
Lei Zhang935738a2021-05-17 21:35:5312#include <initializer_list>
[email protected]c014f2b32013-09-03 23:29:1213#include <iosfwd>
Matt Menkee311c6d2022-06-14 20:17:3914#include <iterator>
dcheng093de9b2016-04-04 21:25:5115#include <memory>
[email protected]8e50b602009-03-03 22:59:4316#include <string>
[email protected]c014f2b32013-09-03 23:29:1217#include <utility>
initial.commitd7cae122008-07-26 21:49:3818#include <vector>
19
[email protected]0bea7252011-08-05 15:34:0020#include "base/base_export.h"
Daniel Cheng782d2ba32022-02-16 19:40:2921#include "base/bit_cast.h"
Daniel Cheng8ac305b2022-02-17 00:05:1122#include "base/compiler_specific.h"
Jan Wilken Dörrie7e7a9792019-10-15 14:42:0523#include "base/containers/checked_iterators.h"
Jan Wilken Dörrie8d9034f12019-11-28 14:48:5724#include "base/containers/checked_range.h"
Lei Zhanga1209af2021-06-26 03:26:2425#include "base/containers/cxx20_erase_vector.h"
mkwstcd8067b2017-04-11 06:52:2126#include "base/containers/flat_map.h"
jdoerriecd022242017-08-23 08:38:2727#include "base/containers/span.h"
asvitkinedbd26533e2015-06-23 18:22:5228#include "base/strings/string_piece.h"
Alexander Timine68aeb32021-04-11 23:06:2129#include "base/trace_event/base_tracing_forward.h"
jdoerrie44efa9d2017-07-14 14:47:2030#include "base/value_iterators.h"
Anton Bikineev7dd58ad2021-05-18 01:01:3931#include "third_party/abseil-cpp/absl/types/optional.h"
Jan Wilken Dörrie79d022142020-08-19 18:18:3232#include "third_party/abseil-cpp/absl/types/variant.h"
initial.commitd7cae122008-07-26 21:49:3833
[email protected]f3a1c642011-07-12 19:15:0334namespace base {
35
initial.commitd7cae122008-07-26 21:49:3836class DictionaryValue;
37class ListValue;
38
Daniel Chenga367fe52022-02-15 18:08:4839// The `Value` class is a variant type can hold one of the following types:
40// - null
41// - bool
42// - int
43// - double
44// - string (internally UTF8-encoded)
45// - binary data (i.e. a blob)
46// - dictionary of string keys to `Value`s
47// - list of `Value`s
[email protected]2f03f532013-07-17 08:43:3348//
Daniel Chenga367fe52022-02-15 18:08:4849// With the exception of binary blobs, `Value` is intended to be the C++ version
50// of data types that can be represented in JSON.
Brett Wilson4bef8ee2017-09-01 20:11:4951//
Daniel Chenga367fe52022-02-15 18:08:4852// Warning: blob support may be removed in the future.
53//
54// ## Usage
55//
56// Do not use `Value` if a more specific type would be more appropriate. For
57// example, a function that only accepts dictionary values should have a
58// `base::Value::Dict` parameter, not a `base::Value` parameter.
59//
60// Construction:
61//
62// `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
63// (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
64// `Value::Dict`, and `Value::List`.
65//
66// Copying:
67//
68// `Value` does not support C++ copy semantics to make it harder to accidentally
69// copy large values. Instead, use `Clone()` to manually create a deep copy.
70//
71// Reading:
72//
73// `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
74// subtype before returning the contained value. `bool`, `int`, `double` are
75// returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
76// are returned by reference.
77//
78// `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
79// the `Value` does not have the correct subtype; otherwise, returns the value
80// wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
81// (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
82//
83// Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
84// when the subtype is `Value::Type::INT`. In that case, the stored value is
85// coerced to a double before being returned.
86//
87// Assignment:
88//
89// It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
90// Instead, wrap the underlying type in `Value` before assigning.
91//
92// ## Dictionaries and Lists
93//
94// `Value` provides the `Value::Dict` and `Value::List` container types for
95// working with dictionaries and lists of values respectively, rather than
96// exposing the underlying container types directly. This allows the types to
97// provide convenient helpers for dictionaries and lists, as well as giving
98// greater flexibility for changing implementation details in the future.
99//
100// Both container types support enough STL-isms to be usable in range-based for
101// loops and generic operations such as those from <algorithm>.
102//
103// Dictionaries support:
104// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
105// `contains()`, `clear()`, `erase()`: Identical to the STL container
106// equivalents, with additional safety checks, e.g. iterators will
107// `CHECK()` if `end()` is dereferenced.
108//
109// - `Clone()`: Create a deep copy.
110// - `Merge()`: Merge another dictionary into this dictionary.
111// - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
112// is not present.
113// - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
114// `Value` also has the correct subtype. Same return semantics as
115// `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
116// `nullptr` if the key is not present or the value has the wrong subtype.
117// - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
118// of the subtypes that `Value` can hold.
119// - `Remove()`: Remove the key from this dictionary, if present.
120// - `Extract()`: If the key is present in the dictionary, removes the key from
121// the dictionary and transfers ownership of `Value` to the caller.
122// Otherwise, returns `absl::nullopt`.
123//
124// Dictionaries also support an additional set of helper methods that operate on
125// "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
126// and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
127// intermediate nested dictionaries, separating the components of the path using
128// '.' characters. For example, finding a string path on a `Value::Dict` using
129// the dotted path:
130//
131// "aaa.bbb.ccc"
132//
133// Will first look for a `Value::Type::DICT` associated with the key "aaa", then
134// another `Value::Type::DICT` under the "aaa" dict associated with the
135// key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
136// with the key "ccc".
137//
Daniel Cheng619653b2022-02-17 18:33:12138// If a path only has one component (i.e. has no dots), please use the regular,
139// non-path APIs.
140//
Daniel Chenga367fe52022-02-15 18:08:48141// Lists support:
142// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
Daniel Chengc9ab0ef2022-02-18 02:34:07143// `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`:
144// Identical to the STL container equivalents, with additional safety
145// checks, e.g. `operator[]` will `CHECK()` if the index is out of range.
Daniel Chenga367fe52022-02-15 18:08:48146// - `Clone()`: Create a deep copy.
147// - `Append()`: Append a value to the end of the list. Accepts `Value` or any
148// of the subtypes that `Value` can hold.
149// - `Insert()`: Insert a `Value` at a specified point in the list.
150// - `EraseValue()`: Erases all matching `Value`s from the list.
151// - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
152// list.
153//
154// ## Refactoring Notes
155//
156// `Value` was originally implemented as a class hierarchy, with a `Value` base
157// class, and a leaf class for each of the different types of `Value` subtypes.
Brett Wilson4bef8ee2017-09-01 20:11:49158// https://docs.google.com/document/d/1uDLu5uTRlCWePxQUEHc8yNQdEoE1BDISYdpggWEABnw
Daniel Chenga367fe52022-02-15 18:08:48159// proposed an overhaul of the `Value` API that has now largely been
160// implemented, though there remains a significant amount of legacy code that is
161// still being migrated as part of the code health migration.
Brett Wilson4bef8ee2017-09-01 20:11:49162//
163// OLD WAY:
164//
165// std::unique_ptr<base::Value> GetFoo() {
166// std::unique_ptr<DictionaryValue> dict;
Daniel Chenga367fe52022-02-15 18:08:48167// dict->SetString("mykey", "foo");
Brett Wilson4bef8ee2017-09-01 20:11:49168// return dict;
169// }
170//
Brett Wilson4bef8ee2017-09-01 20:11:49171// NEW WAY:
172//
173// base::Value GetFoo() {
Daniel Chenga367fe52022-02-15 18:08:48174// base::Value::Dict dict;
Scott Haseley5fd36262022-03-04 19:35:11175// dict.Set("mykey", "abc");
Daniel Chenga367fe52022-02-15 18:08:48176// return base::Value(std::move(dict));
Brett Wilson4bef8ee2017-09-01 20:11:49177// }
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04178//
Daniel Chenga367fe52022-02-15 18:08:48179// To avoid losing type information with the new variant-based design, migration
180// off the deprecated types should use more specific subtypes where possible:
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04181//
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49182// OLD WAY:
183//
184// void AlwaysTakesList(std::unique_ptr<base::ListValue> list);
185// void AlwaysTakesDict(std::unique_ptr<base::DictionaryValue> dict);
186//
Daniel Chenga367fe52022-02-15 18:08:48187// DEPRECATED (PREVIOUS) WAY:
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49188//
189// void AlwaysTakesList(std::vector<base::Value> list);
Daniel Chenga367fe52022-02-15 18:08:48190// void AlwaysTakesListAlternative1(base::Value::ConstListView list);
191// void AlwaysTakesListAlternative2(base::Value::ListView& list);
192// void AlwaysTakesListAlterantive3(base::Value::ListStorage);
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49193// void AlwaysTakesDict(base::flat_map<std::string, base::Value> dict);
Daniel Chenga367fe52022-02-15 18:08:48194// void AlwaysTakesDictAlternative(base::Value::DictStorage);
Daniel Cheng60e6b2d2022-02-05 01:08:46195//
196// NEW WAY:
197//
Daniel Chenga367fe52022-02-15 18:08:48198// void AlwaysTakesList(base::Value::List list);
199// void AlwaysTakesDict(base::Value::Dict dict);
Daniel Cheng60e6b2d2022-02-05 01:08:46200//
Daniel Chenga367fe52022-02-15 18:08:48201// Migrating code may require conversions on API boundaries. If something seems
202// awkward/inefficient, please reach out to #code-health-rotation on Slack for
203// consultation: it is entirely possible that certain classes of APIs may be
204// missing due to an unrealized need.
Daniel Cheng8ac305b2022-02-17 00:05:11205class BASE_EXPORT GSL_OWNER Value {
initial.commitd7cae122008-07-26 21:49:38206 public:
jdoerrie9970f20e2018-07-20 21:41:18207 using BlobStorage = std::vector<uint8_t>;
Daniel Cheng773ce4502022-01-28 15:25:06208
209 using DeprecatedListStorage = std::vector<Value>;
Jan Wilken Dörrief961a372020-11-02 20:30:34210
211 // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is
Matt Menkee311c6d2022-06-14 20:17:39212 // due to legacy reasons, and should be replaced with
213 // flat_map<std::string, Value> once no caller relies on stability of pointers
Matt Menke167ca682022-06-08 23:19:28214 // anymore.
Jan Wilken Dörrief961a372020-11-02 20:30:34215 using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57216
Matt Menke06842489d2022-07-22 00:04:33217 using DeprecatedListView = CheckedContiguousRange<DeprecatedListStorage>;
218 using DeprecatedConstListView =
219 CheckedContiguousConstRange<DeprecatedListStorage>;
Daniel Cheng773ce4502022-01-28 15:25:06220 // TODO(https://crbug.com/1291666): Make these private.
221 using ListView = DeprecatedListView;
222 using ConstListView = DeprecatedConstListView;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57223
Daniel Chenga367fe52022-02-15 18:08:48224 class Dict;
225 class List;
226
Jose Dapena Paz7685422a2019-04-03 18:35:04227 enum class Type : unsigned char {
jdoerriedc72ee942016-12-07 15:43:28228 NONE = 0,
229 BOOLEAN,
230 INTEGER,
231 DOUBLE,
232 STRING,
233 BINARY,
Daniel Chenga367fe52022-02-15 18:08:48234 DICT,
235 // TODO(https://crbug.com/1291670): Deprecated and will be removed.
236 DICTIONARY = DICT,
jdoerriee1b1f3a2019-03-16 04:08:01237 LIST,
[email protected]2f03f532013-07-17 08:43:33238 // Note: Do not add more types. See the file-level comment above for why.
[email protected]a502bbe72011-01-07 18:06:45239 };
240
Lei Zhang30895d52017-10-23 19:14:46241 // Adaptors for converting from the old way to the new way and vice versa.
242 static Value FromUniquePtrValue(std::unique_ptr<Value> val);
243 static std::unique_ptr<Value> ToUniquePtrValue(Value val);
Lei Zhang8c1432b2019-10-08 18:48:54244 static const DictionaryValue& AsDictionaryValue(const Value& val);
245 static const ListValue& AsListValue(const Value& val);
Lei Zhang30895d52017-10-23 19:14:46246
Jan Wilken Dörrie79d022142020-08-19 18:18:32247 Value() noexcept;
jdoerriecc9f5732017-08-23 14:12:30248
Daniel Chenga367fe52022-02-15 18:08:48249 Value(Value&&) noexcept;
250 Value& operator=(Value&&) noexcept;
jdoerriecc9f5732017-08-23 14:12:30251
Daniel Chenga367fe52022-02-15 18:08:48252 // Deleted to prevent accidental copying.
David Bienvenu5f4d4f02020-09-27 16:55:03253 Value(const Value&) = delete;
254 Value& operator=(const Value&) = delete;
jdoerrie05eb3162017-02-01 10:36:56255
Daniel Chenga367fe52022-02-15 18:08:48256 // Creates a deep copy of this value.
257 Value Clone() const;
258
259 // Creates a `Value` of `type`. The data of the corresponding type will be
260 // default constructed.
261 explicit Value(Type type);
262
263 // Constructor for `Value::Type::BOOLEAN`.
264 explicit Value(bool value);
265
266 // Prevent pointers from implicitly converting to bool. Another way to write
267 // this would be to template the bool constructor and use SFINAE to only allow
268 // use if `std::is_same_v<T, bool>` is true, but this has surprising behavior
269 // with range-based for loops over a `std::vector<bool>` (which will
270 // unintuitively match the int overload instead).
271 //
272 // The `const` is load-bearing; otherwise, a `char*` argument would prefer the
273 // deleted overload due to requiring a qualification conversion.
274 template <typename T>
275 explicit Value(const T*) = delete;
276
277 // Constructor for `Value::Type::INT`.
278 explicit Value(int value);
279
280 // Constructor for `Value::Type::DOUBLE`.
281 explicit Value(double value);
282
283 // Constructors for `Value::Type::STRING`.
284 explicit Value(StringPiece value);
285 explicit Value(StringPiece16 value);
286 // `char*` and `char16_t*` are needed to provide a more specific overload than
287 // the deleted `const T*` overload above.
288 explicit Value(const char* value);
289 explicit Value(const char16_t* value);
290 // `std::string&&` allows for efficient move construction.
291 explicit Value(std::string&& value) noexcept;
292
293 // Constructors for `Value::Type::BINARY`.
294 explicit Value(const std::vector<char>& value);
295 explicit Value(base::span<const uint8_t> value);
296 explicit Value(BlobStorage&& value) noexcept;
297
298 // Constructor for `Value::Type::DICT`.
299 explicit Value(Dict&& value) noexcept;
300
301 // Constructor for `Value::Type::LIST`.
302 explicit Value(List&& value) noexcept;
303
jdoerrie8e945542017-02-17 13:54:49304 ~Value();
jdoerrie05eb3162017-02-01 10:36:56305
Gabriel Charetteb49d73a2021-05-05 20:05:59306 // Returns the name for a given `type`.
thestig61709242016-07-19 00:39:30307 static const char* GetTypeName(Type type);
308
initial.commitd7cae122008-07-26 21:49:38309 // Returns the type of the value stored by the current Value object.
Jan Wilken Dörrie79d022142020-08-19 18:18:32310 Type type() const { return static_cast<Type>(data_.index()); }
initial.commitd7cae122008-07-26 21:49:38311
312 // Returns true if the current object represents a given type.
jdoerriecc9f5732017-08-23 14:12:30313 bool is_none() const { return type() == Type::NONE; }
jdoerrie05eb3162017-02-01 10:36:56314 bool is_bool() const { return type() == Type::BOOLEAN; }
315 bool is_int() const { return type() == Type::INTEGER; }
316 bool is_double() const { return type() == Type::DOUBLE; }
317 bool is_string() const { return type() == Type::STRING; }
318 bool is_blob() const { return type() == Type::BINARY; }
Daniel Chenga367fe52022-02-15 18:08:48319 bool is_dict() const { return type() == Type::DICT; }
jdoerrie05eb3162017-02-01 10:36:56320 bool is_list() const { return type() == Type::LIST; }
321
Daniel Chenga367fe52022-02-15 18:08:48322 // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
323 // otherwise. `bool`, `int`, and `double` are returned in a wrapped
324 // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
325 // pointer.
Anton Bikineev7dd58ad2021-05-18 01:01:39326 absl::optional<bool> GetIfBool() const;
327 absl::optional<int> GetIfInt() const;
Daniel Chenga367fe52022-02-15 18:08:48328 // Returns a non-null value for both `Value::Type::DOUBLE` and
329 // `Value::Type::INT`, converting the latter to a double.
Anton Bikineev7dd58ad2021-05-18 01:01:39330 absl::optional<double> GetIfDouble() const;
Jan Wilken Dörrie2e125622021-02-17 10:52:53331 const std::string* GetIfString() const;
Daniel Chenga367fe52022-02-15 18:08:48332 std::string* GetIfString();
Jan Wilken Dörrie2e125622021-02-17 10:52:53333 const BlobStorage* GetIfBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48334 const Dict* GetIfDict() const;
335 Dict* GetIfDict();
336 const List* GetIfList() const;
337 List* GetIfList();
Jan Wilken Dörrie2e125622021-02-17 10:52:53338
Daniel Chenga367fe52022-02-15 18:08:48339 // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
340 // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
341 // `Value::Dict`, and `Value::List` are returned by reference.
jdoerrie05eb3162017-02-01 10:36:56342 bool GetBool() const;
343 int GetInt() const;
Daniel Chenga367fe52022-02-15 18:08:48344 // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
345 // converting the latter to a double.
346 double GetDouble() const;
Daniel Cheng1cdf99782022-06-29 19:25:58347 // Callers that want to transfer ownership can use std::move() in conjunction
348 // with one of the mutable variants below, e.g.:
349 // std::string taken_string = std::move(value.GetString());
350 // base::Value::Dict taken_dict = std::move(value.GetDict());
351 // base::Value::List taken_list = std::move(value.GetList());
jdoerrief38f37b2017-02-01 14:38:32352 const std::string& GetString() const;
Dominic Battre08cbe972019-07-31 03:57:19353 std::string& GetString();
jdoerrie5f12b6272017-04-18 10:22:41354 const BlobStorage& GetBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48355 const Dict& GetDict() const;
356 Dict& GetDict();
357 const List& GetList() const;
358 List& GetList();
359
360 // Represents a dictionary of string keys to Values.
Daniel Cheng8ac305b2022-02-17 00:05:11361 class BASE_EXPORT GSL_OWNER Dict {
Daniel Chenga367fe52022-02-15 18:08:48362 public:
363 using iterator = detail::dict_iterator;
364 using const_iterator = detail::const_dict_iterator;
365
366 Dict();
367
368 Dict(Dict&&) noexcept;
369 Dict& operator=(Dict&&) noexcept;
370
371 // Deleted to prevent accidental copying.
372 Dict(const Dict&) = delete;
373 Dict& operator=(const Dict&) = delete;
374
Matt Menkee311c6d2022-06-14 20:17:39375 // Takes move_iterators iterators that return std::pair<std::string, Value>,
376 // and moves their values into a new Dict. Adding all entries at once
377 // results in a faster initial sort operation. Takes move iterators to avoid
378 // having to clone the input.
379 template <class IteratorType>
380 explicit Dict(std::move_iterator<IteratorType> first,
381 std::move_iterator<IteratorType> last) {
382 // Need to move into a vector first, since `storage_` currently uses
383 // unique_ptrs.
384 std::vector<std::pair<std::string, std::unique_ptr<Value>>> values;
385 for (auto current = first; current != last; ++current) {
386 // With move iterators, no need to call Clone(), but do need to move
387 // to a temporary first, as accessing either field individually will
388 // directly from the iterator will delete the other field.
389 auto value = *current;
390 values.emplace_back(std::move(value.first),
391 std::make_unique<Value>(std::move(value.second)));
392 }
393 storage_ =
394 flat_map<std::string, std::unique_ptr<Value>>(std::move(values));
395 }
396
Daniel Chenga367fe52022-02-15 18:08:48397 ~Dict();
398
399 // TODO(dcheng): Probably need to allow construction from a pair of
400 // iterators for now due to the prevalence of DictStorage.
401
402 // Returns true if there are no entries in this dictionary and false
403 // otherwise.
404 bool empty() const;
405
406 // Returns the number of entries in this dictionary.
407 size_t size() const;
408
409 // Returns an iterator to the first entry in this dictionary.
410 iterator begin();
411 const_iterator begin() const;
412 const_iterator cbegin() const;
413
414 // Returns an iterator following the last entry in this dictionary. May not
415 // be dereferenced.
416 iterator end();
417 const_iterator end() const;
418 const_iterator cend() const;
419
420 // Returns true if `key` is an entry in this dictionary.
421 bool contains(base::StringPiece key) const;
422
423 // Removes all entries from this dictionary.
424 void clear();
425
426 // Removes the entry referenced by `pos` in this dictionary and returns an
427 // iterator to the entry following the removed entry.
428 iterator erase(iterator pos);
429 iterator erase(const_iterator pos);
430
431 // Creates a deep copy of this dictionary.
432 Dict Clone() const;
433
434 // Merges the entries from `dict` into this dictionary. If an entry with the
435 // same key exists in this dictionary and `dict`:
436 // - if both entries are dictionaries, they will be recursively merged
437 // - otherwise, the already-existing entry in this dictionary will be
438 // overwritten with the entry from `dict`.
Daniel Cheng1cdf99782022-06-29 19:25:58439 void Merge(Dict dict);
Daniel Chenga367fe52022-02-15 18:08:48440
441 // Finds the entry corresponding to `key` in this dictionary. Returns
442 // nullptr if there is no such entry.
443 const Value* Find(StringPiece key) const;
444 Value* Find(StringPiece key);
445
446 // Similar to `Find()` above, but returns `absl::nullopt`/`nullptr` if the
447 // type of the entry does not match. `bool`, `int`, and `double` are
448 // returned in a wrapped `absl::optional`; blobs, `Value::Dict`, and
449 // `Value::List` are returned by pointer.
450 absl::optional<bool> FindBool(StringPiece key) const;
451 absl::optional<int> FindInt(StringPiece key) const;
452 // Returns a non-null value for both `Value::Type::DOUBLE` and
453 // `Value::Type::INT`, converting the latter to a double.
454 absl::optional<double> FindDouble(StringPiece key) const;
455 const std::string* FindString(StringPiece key) const;
456 std::string* FindString(StringPiece key);
457 const BlobStorage* FindBlob(StringPiece key) const;
458 const Dict* FindDict(StringPiece key) const;
459 Dict* FindDict(StringPiece key);
460 const List* FindList(StringPiece key) const;
461 List* FindList(StringPiece key);
462
463 // Sets an entry with `key` and `value` in this dictionary, overwriting any
464 // existing entry with the same `key`. Returns a pointer to the set `value`.
465 Value* Set(StringPiece key, Value&& value);
466 Value* Set(StringPiece key, bool value);
467 template <typename T>
468 Value* Set(StringPiece, const T*) = delete;
469 Value* Set(StringPiece key, int value);
470 Value* Set(StringPiece key, double value);
471 Value* Set(StringPiece key, StringPiece value);
472 Value* Set(StringPiece key, StringPiece16 value);
473 Value* Set(StringPiece key, const char* value);
474 Value* Set(StringPiece key, const char16_t* value);
475 Value* Set(StringPiece key, std::string&& value);
476 Value* Set(StringPiece key, BlobStorage&& value);
477 Value* Set(StringPiece key, Dict&& value);
478 Value* Set(StringPiece key, List&& value);
479
480 // Removes the entry corresponding to `key` from this dictionary. Returns
481 // true if an entry was removed or false otherwise.
482 bool Remove(StringPiece key);
483
484 // Similar to `Remove()`, but returns the value corresponding to the removed
485 // entry or `absl::nullopt` otherwise.
486 absl::optional<Value> Extract(StringPiece key);
487
488 // Equivalent to the above methods but operating on paths instead of keys.
489 // A path is shorthand syntax for referring to a key nested inside
490 // intermediate dictionaries, with components delimited by ".". Paths may
491 // not be empty.
492 //
Daniel Cheng619653b2022-02-17 18:33:12493 // Prefer the non-path methods above when possible. Paths that have only one
494 // component (i.e. no dots in the path) should never use the path-based
495 // methods.
496 //
497 // Originally, the path-based APIs were the only way of specifying a key, so
498 // there are likely to be many legacy (and unnecessary) uses of the path
499 // APIs that do not actually require traversing nested dictionaries.
Daniel Chenga367fe52022-02-15 18:08:48500 const Value* FindByDottedPath(StringPiece path) const;
501 Value* FindByDottedPath(StringPiece path);
502
503 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
504 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
505 // Returns a non-null value for both `Value::Type::DOUBLE` and
506 // `Value::Type::INT`, converting the latter to a double.
507 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
508 const std::string* FindStringByDottedPath(StringPiece path) const;
509 std::string* FindStringByDottedPath(StringPiece path);
510 const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
511 const Dict* FindDictByDottedPath(StringPiece path) const;
512 Dict* FindDictByDottedPath(StringPiece path);
513 const List* FindListByDottedPath(StringPiece path) const;
514 List* FindListByDottedPath(StringPiece path);
515
Daniel Cheng619653b2022-02-17 18:33:12516 // Creates a new entry with a dictionary for any non-last component that is
517 // missing an entry while performing the path traversal. Will fail if any
518 // non-last component of the path refers to an already-existing entry that
519 // is not a dictionary. Returns `nullptr` on failure.
Daniel Chenga367fe52022-02-15 18:08:48520 Value* SetByDottedPath(StringPiece path, Value&& value);
521 Value* SetByDottedPath(StringPiece path, bool value);
522 template <typename T>
523 Value* SetByDottedPath(StringPiece, const T*) = delete;
524 Value* SetByDottedPath(StringPiece path, int value);
525 Value* SetByDottedPath(StringPiece path, double value);
526 Value* SetByDottedPath(StringPiece path, StringPiece value);
527 Value* SetByDottedPath(StringPiece path, StringPiece16 value);
528 Value* SetByDottedPath(StringPiece path, const char* value);
529 Value* SetByDottedPath(StringPiece path, const char16_t* value);
530 Value* SetByDottedPath(StringPiece path, std::string&& value);
531 Value* SetByDottedPath(StringPiece path, BlobStorage&& value);
532 Value* SetByDottedPath(StringPiece path, Dict&& value);
533 Value* SetByDottedPath(StringPiece path, List&& value);
534
535 bool RemoveByDottedPath(StringPiece path);
536
537 absl::optional<Value> ExtractByDottedPath(StringPiece path);
538
Scott Haseleye51040782022-03-09 17:32:37539 // Serializes to a string for logging and debug purposes.
540 std::string DebugString() const;
541
Daniel Chengb5862bc2022-06-09 17:04:06542#if BUILDFLAG(ENABLE_BASE_TRACING)
543 // Write this object into a trace.
544 void WriteIntoTrace(perfetto::TracedValue) const;
545#endif // BUILDFLAG(ENABLE_BASE_TRACING)
546
Daniel Chenga367fe52022-02-15 18:08:48547 private:
548 BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs);
549 BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs);
550 BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs);
551 BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
552 BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
553 BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);
554
555 // For legacy access to the internal storage type.
556 friend Value;
557
558 explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);
559
560 flat_map<std::string, std::unique_ptr<Value>> storage_;
561 };
562
563 // Represents a list of Values.
Daniel Cheng8ac305b2022-02-17 00:05:11564 class BASE_EXPORT GSL_OWNER List {
Daniel Chenga367fe52022-02-15 18:08:48565 public:
566 using iterator = CheckedContiguousIterator<Value>;
567 using const_iterator = CheckedContiguousConstIterator<Value>;
Jan Keitel56a92682022-07-11 11:19:21568 using value_type = Value;
Daniel Chenga367fe52022-02-15 18:08:48569
570 List();
571
572 List(List&&) noexcept;
573 List& operator=(List&&) noexcept;
574
575 // Deleted to prevent accidental copying.
576 List(const List&) = delete;
577 List& operator=(const List&) = delete;
578
579 ~List();
580
581 // TODO(dcheng): Probably need to allow construction from a pair of
582 // iterators for now due to the prevalence of ListStorage now.
583
584 // Returns true if there are no values in this list and false otherwise.
585 bool empty() const;
586
587 // Returns the number of values in this list.
588 size_t size() const;
589
590 // Returns an iterator to the first value in this list.
591 iterator begin();
592 const_iterator begin() const;
593 const_iterator cbegin() const;
594
595 // Returns an iterator following the last value in this list. May not be
596 // dereferenced.
597 iterator end();
598 const_iterator end() const;
599 const_iterator cend() const;
600
Daniel Chengc9ab0ef2022-02-18 02:34:07601 // Returns a reference to the first value in the container. Fails with
602 // `CHECK()` if the list is empty.
603 const Value& front() const;
604 Value& front();
605
606 // Returns a reference to the last value in the container. Fails with
607 // `CHECK()` if the list is empty.
608 const Value& back() const;
609 Value& back();
610
611 // Increase the capacity of the backing container, but does not change
612 // the size. Assume all existing iterators will be invalidated.
613 void reserve(size_t capacity);
614
Daniel Chenga367fe52022-02-15 18:08:48615 // Returns a reference to the value at `index` in this list. Fails with a
616 // `CHECK()` if `index >= size()`.
617 const Value& operator[](size_t index) const;
618 Value& operator[](size_t index);
619
620 // Removes all value from this list.
621 void clear();
622
Daniel Chengc9ab0ef2022-02-18 02:34:07623 // Removes the value referenced by `pos` in this list and returns an
624 // iterator to the value following the removed value.
Daniel Chenga367fe52022-02-15 18:08:48625 iterator erase(iterator pos);
626 const_iterator erase(const_iterator pos);
627
Matt Menke3a0de712022-07-14 23:45:08628 // Remove the values in the range [`first`, `last`). Returns iterator to the
629 // first value following the removed range, which is `last`. If `first` ==
630 // `last`, removes nothing and returns `last`.
631 iterator erase(iterator first, iterator last);
632 const_iterator erase(const_iterator first, const_iterator last);
633
Daniel Chenga367fe52022-02-15 18:08:48634 // Creates a deep copy of this dictionary.
635 List Clone() const;
636
637 // Appends `value` to the end of this list.
638 void Append(Value&& value);
639 void Append(bool value);
640 template <typename T>
641 void Append(const T*) = delete;
642 void Append(int value);
643 void Append(double value);
644 void Append(StringPiece value);
645 void Append(StringPiece16 value);
646 void Append(const char* value);
647 void Append(const char16_t* value);
648 void Append(std::string&& value);
649 void Append(BlobStorage&& value);
650 void Append(Dict&& value);
651 void Append(List&& value);
652
653 // Inserts `value` before `pos` in this list. Returns an iterator to the
654 // inserted value.
655 // TODO(dcheng): Should this provide the same set of overloads that Append()
656 // does?
657 iterator Insert(const_iterator pos, Value&& value);
658
659 // Erases all values equal to `value` from this list.
660 size_t EraseValue(const Value& value);
661
662 // Erases all values for which `predicate` evaluates to true from this list.
663 template <typename Predicate>
664 size_t EraseIf(Predicate predicate) {
665 return base::EraseIf(storage_, predicate);
666 }
667
Scott Haseleye51040782022-03-09 17:32:37668 // Serializes to a string for logging and debug purposes.
669 std::string DebugString() const;
670
Daniel Chengb5862bc2022-06-09 17:04:06671#if BUILDFLAG(ENABLE_BASE_TRACING)
672 // Write this object into a trace.
673 void WriteIntoTrace(perfetto::TracedValue) const;
674#endif // BUILDFLAG(ENABLE_BASE_TRACING)
675
Daniel Chenga367fe52022-02-15 18:08:48676 private:
677 BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
678 BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
679 BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
680 BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
681 BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
682 BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);
683
684 // For legacy access to the internal storage type.
685 friend Value;
686
687 explicit List(const std::vector<Value>& storage);
688
689 std::vector<Value> storage_;
690 };
jdoerriee03e80f2017-02-15 08:42:14691
Daniel Cheng619653b2022-02-17 18:33:12692 // ===== DEPRECATED methods that require `type() == Type::LIST` =====
693
Jan Wilken Dörrie69a65a3a2020-01-16 15:03:30694 // Returns the Values in a list as a view. The mutable overload allows for
695 // modification of the underlying values, but does not allow changing the
Matt Menke5f2ff7b2022-06-30 16:49:27696 // structure of the list.
Daniel Cheng619653b2022-02-17 18:33:12697 //
698 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
699 // `GetList()` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06700 DeprecatedListView GetListDeprecated();
701 DeprecatedConstListView GetListDeprecated() const;
jdoerrie2b7d0fcd2017-04-19 07:15:38702
Gabriel Charetteb49d73a2021-05-05 20:05:59703 // Appends `value` to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:12704 //
705 // DEPRECATED: prefer `Value::List::Append()`.
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24706 void Append(Value&& value);
Daniel Cheng619653b2022-02-17 18:33:12707 // DEPRECATED: prefer `Value::List::Append()`.
708 void Append(bool value);
709 template <typename T>
710 void Append(const T* ptr) = delete;
711 // DEPRECATED: prefer `Value::List::Append()`.
712 void Append(int value);
713 // DEPRECATED: prefer `Value::List::Append()`.
714 void Append(double value);
715 // DEPRECATED: prefer `Value::List::Append()`.
716 void Append(StringPiece value);
717 // DEPRECATED: prefer `Value::List::Append()`.
718 void Append(StringPiece16 value);
719 // DEPRECATED: prefer `Value::List::Append()`.
720 void Append(const char* value);
721 // DEPRECATED: prefer `Value::List::Append()`.
Daniel Cheng619653b2022-02-17 18:33:12722 void Append(std::string&& value);
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24723
Gabriel Charetteb49d73a2021-05-05 20:05:59724 // Inserts `value` before `pos`.
Daniel Cheng619653b2022-02-17 18:33:12725 //
726 // DEPRECATED: prefer `Value::List::Insert()`.
Jan Wilken Dörrie9065545e12019-10-30 10:44:51727 CheckedContiguousIterator<Value> Insert(
728 CheckedContiguousConstIterator<Value> pos,
729 Value&& value);
730
Gabriel Charetteb49d73a2021-05-05 20:05:59731 // Erases the Value pointed to by `iter`. Returns false if `iter` is out of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05732 // bounds.
Daniel Cheng619653b2022-02-17 18:33:12733 //
734 // DEPRECATED: prefer `Value::List::erase(iter)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05735 bool EraseListIter(CheckedContiguousConstIterator<Value> iter);
736
Gabriel Charetteb49d73a2021-05-05 20:05:59737 // Erases all Values that compare equal to `val`. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05738 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12739 //
740 // DEPRECATED: prefer `Value::List::EraseValue(val)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05741 size_t EraseListValue(const Value& val);
742
Gabriel Charetteb49d73a2021-05-05 20:05:59743 // Erases all Values for which `pred` returns true. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05744 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12745 //
746 // DEPRECATED: prefer `Value::List::EraseIf(pred)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05747 template <typename Predicate>
748 size_t EraseListValueIf(Predicate pred) {
Jan Wilken Dörrie79d022142020-08-19 18:18:32749 return base::EraseIf(list(), pred);
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05750 }
751
Jan Wilken Dörrie02577a22019-12-04 14:27:39752 // Erases all Values from the list.
Daniel Cheng619653b2022-02-17 18:33:12753 //
754 // DEPRECATED: prefer `Value::List::clear()`.
Jan Wilken Dörrie02577a22019-12-04 14:27:39755 void ClearList();
756
Daniel Cheng619653b2022-02-17 18:33:12757 // ===== DEPRECATED methods that require `type() == Type::DICT` =====
758
Gabriel Charetteb49d73a2021-05-05 20:05:59759 // `FindKey` looks up `key` in the underlying dictionary. If found, it returns
jdoerrie78ab7a22017-08-17 19:04:45760 // a pointer to the element. Otherwise it returns nullptr.
jdoerrie78ab7a22017-08-17 19:04:45761 //
Daniel Cheng619653b2022-02-17 18:33:12762 // DEPRECATED: prefer `Value::Dict::Find()`.
jdoerrie78ab7a22017-08-17 19:04:45763 Value* FindKey(StringPiece key);
764 const Value* FindKey(StringPiece key) const;
jdoerrie44efa9d2017-07-14 14:47:20765
Gabriel Charetteb49d73a2021-05-05 20:05:59766 // `FindKeyOfType` is similar to `FindKey`, but it also requires the found
767 // value to have type `type`. If no type is found, or the found value is of a
jdoerrie78ab7a22017-08-17 19:04:45768 // different type nullptr is returned.
jdoerrie78ab7a22017-08-17 19:04:45769 //
Daniel Cheng619653b2022-02-17 18:33:12770 // DEPRECATED: prefer `Value::Dict::FindBool()`, `Value::Dict::FindInt()`, et
771 // cetera.
jdoerrie78ab7a22017-08-17 19:04:45772 Value* FindKeyOfType(StringPiece key, Type type);
773 const Value* FindKeyOfType(StringPiece key, Type type) const;
jdoerrie44efa9d2017-07-14 14:47:20774
Daniel Cheng619653b2022-02-17 18:33:12775 // These are convenience forms of `FindKey`. They return `absl::nullopt` or
776 // `nullptr` if the value is not found or doesn't have the type specified in
777 // the function's name.
778 //
779 // DEPRECATED: prefer `Value::Dict::FindBool()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39780 absl::optional<bool> FindBoolKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12781 // DEPRECATED: prefer `Value::Dict::FindInt()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39782 absl::optional<int> FindIntKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12783 // Returns a non-null value for both `Value::Type::DOUBLE` and
784 // `Value::Type::INT`, converting the latter to a double.
785 //
786 // DEPRECATED: prefer `Value::Dict::FindDouble()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39787 absl::optional<double> FindDoubleKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12788 // DEPRECATED: prefer `Value::Dict::FindString()`.
Vladislav Kuzkokov193a2ba2019-01-08 11:33:16789 const std::string* FindStringKey(StringPiece key) const;
Dominic Battre08cbe972019-07-31 03:57:19790 std::string* FindStringKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12791 // DEPRECATED: prefer `Value::Dict::FindBlob()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06792 const BlobStorage* FindBlobKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12793 // DEPRECATED: prefer `Value::Dict::FindDict()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06794 const Value* FindDictKey(StringPiece key) const;
795 Value* FindDictKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12796 // DEPRECATED: prefer `Value::Dict::FindList()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06797 const Value* FindListKey(StringPiece key) const;
798 Value* FindListKey(StringPiece key);
799
Gabriel Charetteb49d73a2021-05-05 20:05:59800 // `SetKey` looks up `key` in the underlying dictionary and sets the mapped
801 // value to `value`. If `key` could not be found, a new element is inserted.
jdoerrie78ab7a22017-08-17 19:04:45802 // A pointer to the modified item is returned.
jdoerrie78ab7a22017-08-17 19:04:45803 //
Daniel Cheng619653b2022-02-17 18:33:12804 // Note: Prefer `Set<Type>Key()` if the input is not already a `Value`.
805 //
806 // DEPRECATED: Prefer `Value::Dict::Set()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16807 Value* SetKey(StringPiece key, Value&& value);
jdoerrie44efa9d2017-07-14 14:47:20808
Gabriel Charetteb49d73a2021-05-05 20:05:59809 // `Set`Type>Key` looks up `key` in the underlying dictionary and associates a
810 // corresponding Value() constructed from the second parameter. Compared to
811 // `SetKey()`, this avoids un-necessary temporary `Value()` creation, as well
David 'Digit' Turnere169e6c2019-03-28 22:06:29812 // ambiguities in the value type.
Daniel Cheng619653b2022-02-17 18:33:12813 //
814 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29815 Value* SetBoolKey(StringPiece key, bool val);
Daniel Cheng619653b2022-02-17 18:33:12816 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29817 Value* SetIntKey(StringPiece key, int val);
Daniel Cheng619653b2022-02-17 18:33:12818 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29819 Value* SetDoubleKey(StringPiece key, double val);
Daniel Cheng619653b2022-02-17 18:33:12820 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29821 Value* SetStringKey(StringPiece key, StringPiece val);
Daniel Cheng619653b2022-02-17 18:33:12822 // DEPRECATED: Prefer `Value::Dict::Set()`.
Jan Wilken Dörrie293405a2020-05-12 19:45:11823 Value* SetStringKey(StringPiece key, StringPiece16 val);
Daniel Cheng619653b2022-02-17 18:33:12824 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29825 Value* SetStringKey(StringPiece key, const char* val);
Daniel Cheng619653b2022-02-17 18:33:12826 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29827 Value* SetStringKey(StringPiece key, std::string&& val);
David 'Digit' Turnere169e6c2019-03-28 22:06:29828
Gabriel Charetteb49d73a2021-05-05 20:05:59829 // This attempts to remove the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46830 // failure, e.g. the key does not exist, false is returned and the underlying
Gabriel Charetteb49d73a2021-05-05 20:05:59831 // dictionary is not changed. In case of success, `key` is deleted from the
jdoerriec209c7d2019-04-05 09:51:46832 // dictionary and the method returns true.
jdoerrie64783162017-09-04 16:33:32833 //
Daniel Cheng619653b2022-02-17 18:33:12834 // Deprecated: Prefer `Value::Dict::Remove()`.
jdoerrie64783162017-09-04 16:33:32835 bool RemoveKey(StringPiece key);
836
Gabriel Charetteb49d73a2021-05-05 20:05:59837 // This attempts to extract the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46838 // failure, e.g. the key does not exist, nullopt is returned and the
Gabriel Charetteb49d73a2021-05-05 20:05:59839 // underlying dictionary is not changed. In case of success, `key` is deleted
jdoerriec209c7d2019-04-05 09:51:46840 // from the dictionary and the method returns the extracted Value.
jdoerriec209c7d2019-04-05 09:51:46841 //
Daniel Cheng619653b2022-02-17 18:33:12842 // DEPRECATED: Prefer `Value::Dict::Extract()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39843 absl::optional<Value> ExtractKey(StringPiece key);
jdoerriec209c7d2019-04-05 09:51:46844
Brett Wilsond16cf4ee2017-08-03 00:08:27845 // Searches a hierarchy of dictionary values for a given value. If a path
846 // of dictionaries exist, returns the item at that path. If any of the path
847 // components do not exist or if any but the last path components are not
Daniel Cheng619653b2022-02-17 18:33:12848 // dictionaries, returns nullptr. The type of the leaf Value is not checked.
Brett Wilsond16cf4ee2017-08-03 00:08:27849 //
David 'Digit' Turner43ce6492019-04-04 16:04:44850 // This version takes a StringPiece for the path, using dots as separators.
Daniel Cheng619653b2022-02-17 18:33:12851 //
852 // DEPRECATED: Prefer `Value::Dict::FindByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44853 Value* FindPath(StringPiece path);
854 const Value* FindPath(StringPiece path) const;
855
856 // There are also deprecated versions that take the path parameter
857 // as either a std::initializer_list<StringPiece> or a
858 // span<const StringPiece>. The latter is useful to use a
859 // std::vector<std::string> as a parameter but creates huge dynamic
jdoerriec209c7d2019-04-05 09:51:46860 // allocations and should be avoided!
Gabriel Charetteb49d73a2021-05-05 20:05:59861 // Note: If there is only one component in the path, use `FindKey()` instead.
jdoerriec209c7d2019-04-05 09:51:46862 //
David 'Digit' Turner43ce6492019-04-04 16:04:44863 // Example:
jdoerriecd022242017-08-23 08:38:27864 // std::vector<StringPiece> components = ...
865 // auto* found = FindPath(components);
Daniel Cheng619653b2022-02-17 18:33:12866 //
867 // DEPRECATED: These are not common, and there is no currently planned
868 // replacement.
jdoerriecd022242017-08-23 08:38:27869 Value* FindPath(std::initializer_list<StringPiece> path);
870 Value* FindPath(span<const StringPiece> path);
871 const Value* FindPath(std::initializer_list<StringPiece> path) const;
872 const Value* FindPath(span<const StringPiece> path) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27873
Lei Zhange0fc6f02017-10-27 00:27:23874 // Like FindPath() but will only return the value if the leaf Value type
Brett Wilsond16cf4ee2017-08-03 00:08:27875 // matches the given type. Will return nullptr otherwise.
Gabriel Charetteb49d73a2021-05-05 20:05:59876 // Note: Prefer `Find<Type>Path()` for simple values.
Lei Zhange0fc6f02017-10-27 00:27:23877 //
Gabriel Charetteb49d73a2021-05-05 20:05:59878 // Note: If there is only one component in the path, use `FindKeyOfType()`
David 'Digit' Turner43ce6492019-04-04 16:04:44879 // instead for slightly better performance.
Daniel Cheng619653b2022-02-17 18:33:12880 //
881 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`,
882 // `Value::Dict::FindIntByDottedPath()`, et cetera.
David 'Digit' Turner43ce6492019-04-04 16:04:44883 Value* FindPathOfType(StringPiece path, Type type);
884 const Value* FindPathOfType(StringPiece path, Type type) const;
885
886 // Convenience accessors used when the expected type of a value is known.
887 // Similar to Find<Type>Key() but accepts paths instead of keys.
Daniel Cheng619653b2022-02-17 18:33:12888 //
889 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`, or
890 // `Value::Dict::FindBool()` if the path only has one component, i.e. has no
891 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39892 absl::optional<bool> FindBoolPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12893 // DEPRECATED: Use `Value::Dict::FindIntByDottedPath()`, or
894 // `Value::Dict::FindInt()` if the path only has one component, i.e. has no
895 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39896 absl::optional<int> FindIntPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12897 // DEPRECATED: Use `Value::Dict::FindDoubleByDottedPath()`, or
898 // `Value::Dict::FindDouble()` if the path only has one component, i.e. has no
899 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39900 absl::optional<double> FindDoublePath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12901 // DEPRECATED: Use `Value::Dict::FindStringByDottedPath()`, or
902 // `Value::Dict::FindString()` if the path only has one component, i.e. has no
903 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44904 const std::string* FindStringPath(StringPiece path) const;
Dominic Battre08cbe972019-07-31 03:57:19905 std::string* FindStringPath(StringPiece path);
Daniel Cheng619653b2022-02-17 18:33:12906 // DEPRECATED: Use `Value::Dict::FindDictByDottedPath()`, or
907 // `Value::Dict::FindDict()` if the path only has one component, i.e. has no
908 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44909 Value* FindDictPath(StringPiece path);
910 const Value* FindDictPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12911 // DEPRECATED: Use `Value::Dict::FindListByDottedPath()`, or
912 // `Value::Dict::FindList()` if the path only has one component, i.e. has no
913 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44914 Value* FindListPath(StringPiece path);
915 const Value* FindListPath(StringPiece path) const;
916
917 // The following forms are deprecated too, use the ones that take the path
918 // as a single StringPiece instead.
Daniel Cheng619653b2022-02-17 18:33:12919 //
920 // DEPRECATED: These are not common, and there is no currently planned
921 // replacement.
jdoerriecd022242017-08-23 08:38:27922 Value* FindPathOfType(std::initializer_list<StringPiece> path, Type type);
923 Value* FindPathOfType(span<const StringPiece> path, Type type);
924 const Value* FindPathOfType(std::initializer_list<StringPiece> path,
Brett Wilsond16cf4ee2017-08-03 00:08:27925 Type type) const;
jdoerriecd022242017-08-23 08:38:27926 const Value* FindPathOfType(span<const StringPiece> path, Type type) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27927
928 // Sets the given path, expanding and creating dictionary keys as necessary.
929 //
jdoerrie64783162017-09-04 16:33:32930 // If the current value is not a dictionary, the function returns nullptr. If
931 // path components do not exist, they will be created. If any but the last
932 // components matches a value that is not a dictionary, the function will fail
933 // (it will not overwrite the value) and return nullptr. The last path
934 // component will be unconditionally overwritten if it exists, and created if
935 // it doesn't.
Brett Wilsond16cf4ee2017-08-03 00:08:27936 //
Gabriel Charetteb49d73a2021-05-05 20:05:59937 // Note: If there is only one component in the path, use `SetKey()` instead.
938 // Note: Using `Set<Type>Path()` might be more convenient and efficient.
Daniel Cheng619653b2022-02-17 18:33:12939 //
940 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44941 Value* SetPath(StringPiece path, Value&& value);
942
943 // These setters are more convenient and efficient than the corresponding
944 // SetPath(...) call.
Daniel Cheng619653b2022-02-17 18:33:12945 //
946 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44947 Value* SetBoolPath(StringPiece path, bool value);
Daniel Cheng619653b2022-02-17 18:33:12948 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44949 Value* SetIntPath(StringPiece path, int value);
Daniel Cheng619653b2022-02-17 18:33:12950 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44951 Value* SetDoublePath(StringPiece path, double value);
Daniel Cheng619653b2022-02-17 18:33:12952 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44953 Value* SetStringPath(StringPiece path, StringPiece value);
Daniel Cheng619653b2022-02-17 18:33:12954 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44955 Value* SetStringPath(StringPiece path, const char* value);
Daniel Cheng619653b2022-02-17 18:33:12956 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44957 Value* SetStringPath(StringPiece path, std::string&& value);
Daniel Cheng619653b2022-02-17 18:33:12958 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44959 Value* SetStringPath(StringPiece path, StringPiece16 value);
960
Daniel Cheng619653b2022-02-17 18:33:12961 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16962 Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
963 Value* SetPath(span<const StringPiece> path, Value&& value);
Brett Wilsond16cf4ee2017-08-03 00:08:27964
jdoerrie64783162017-09-04 16:33:32965 // Tries to remove a Value at the given path.
966 //
jdoerriec209c7d2019-04-05 09:51:46967 // If the current value is not a dictionary or any path component does not
jdoerrie64783162017-09-04 16:33:32968 // exist, this operation fails, leaves underlying Values untouched and returns
Gabriel Charetteb49d73a2021-05-05 20:05:59969 // `false`. In case intermediate dictionaries become empty as a result of this
jdoerrie64783162017-09-04 16:33:32970 // path removal, they will be removed as well.
Song Fangzhen09e06912021-07-21 15:01:28971 // Note: If there is only one component in the path, use `RemoveKey()`
Gabriel Charetteb49d73a2021-05-05 20:05:59972 // instead.
jdoerrie64783162017-09-04 16:33:32973 //
Daniel Cheng619653b2022-02-17 18:33:12974 // DEPRECATED: Use `Value::Dict::RemoveByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44975 bool RemovePath(StringPiece path);
976
jdoerriec209c7d2019-04-05 09:51:46977 // Tries to extract a Value at the given path.
978 //
979 // If the current value is not a dictionary or any path component does not
980 // exist, this operation fails, leaves underlying Values untouched and returns
981 // nullopt. In case intermediate dictionaries become empty as a result of this
982 // path removal, they will be removed as well. Returns the extracted value on
983 // success.
Gabriel Charetteb49d73a2021-05-05 20:05:59984 // Note: If there is only one component in the path, use `ExtractKey()`
985 // instead.
jdoerriec209c7d2019-04-05 09:51:46986 //
Daniel Cheng619653b2022-02-17 18:33:12987 // DEPRECATED: Use `Value::Dict::ExtractByDottedPath()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39988 absl::optional<Value> ExtractPath(StringPiece path);
jdoerriec209c7d2019-04-05 09:51:46989
jdoerrie78ab7a22017-08-17 19:04:45990 using dict_iterator_proxy = detail::dict_iterator_proxy;
991 using const_dict_iterator_proxy = detail::const_dict_iterator_proxy;
jdoerrie44efa9d2017-07-14 14:47:20992
Gabriel Charetteb49d73a2021-05-05 20:05:59993 // `DictItems` returns a proxy object that exposes iterators to the underlying
jdoerrie44efa9d2017-07-14 14:47:20994 // dictionary. These are intended for iteration over all items in the
995 // dictionary and are compatible with for-each loops and standard library
996 // algorithms.
David Van Cleve373381d2020-01-07 18:16:13997 //
Gabriel Charetteb49d73a2021-05-05 20:05:59998 // Unlike with std::map, a range-for over the non-const version of
999 // `DictItems()` will range over items of type
1000 // `pair<const std::string&, Value&>`, so code of the form
David Van Cleve373381d2020-01-07 18:16:131001 // for (auto kv : my_value.DictItems())
1002 // Mutate(kv.second);
Gabriel Charetteb49d73a2021-05-05 20:05:591003 // will actually alter `my_value` in place (if it isn't const).
David Van Cleve373381d2020-01-07 18:16:131004 //
Daniel Cheng619653b2022-02-17 18:33:121005 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1006 // instead.
jdoerrie44efa9d2017-07-14 14:47:201007 dict_iterator_proxy DictItems();
1008 const_dict_iterator_proxy DictItems() const;
1009
Daniel Cheng619653b2022-02-17 18:33:121010 // DEPRECATED: prefer `Value::Dict::size()`.
Lei Zhange823c512018-05-07 20:27:301011 size_t DictSize() const;
Daniel Cheng619653b2022-02-17 18:33:121012
1013 // DEPRECATED: prefer `Value::Dict::empty()`.
Lei Zhange823c512018-05-07 20:27:301014 bool DictEmpty() const;
Daniel Cheng619653b2022-02-17 18:33:121015
1016 // DEPRECATED: prefer `Value::Dict::clear()`.
Panos Astithas0532a862020-10-29 04:15:071017 void DictClear();
Lei Zhange823c512018-05-07 20:27:301018
Gabriel Charetteb49d73a2021-05-05 20:05:591019 // Merge `dictionary` into this value. This is done recursively, i.e. any
jdoerriec1091282018-08-01 17:28:121020 // sub-dictionaries will be merged as well. In case of key collisions, the
1021 // passed in dictionary takes precedence and data already present will be
Gabriel Charetteb49d73a2021-05-05 20:05:591022 // replaced. Values within `dictionary` are deep-copied, so `dictionary` may
jdoerriec1091282018-08-01 17:28:121023 // be freed any time after this call.
Gabriel Charetteb49d73a2021-05-05 20:05:591024 // Note: This requires that `type()` and `dictionary->type()` is
Daniel Chenga367fe52022-02-15 18:08:481025 // Type::DICT.
Daniel Cheng619653b2022-02-17 18:33:121026 //
1027 // DEPRECATED: prefer `Value::Dict::Merge()`.
jdoerriec1091282018-08-01 17:28:121028 void MergeDictionary(const Value* dictionary);
1029
[email protected]2f03f532013-07-17 08:43:331030 // These methods allow the convenient retrieval of the contents of the Value.
1031 // If the current object can be converted into the given type, the value is
Gabriel Charetteb49d73a2021-05-05 20:05:591032 // returned through the `out_value` parameter and true is returned;
1033 // otherwise, false is returned and `out_value` is unchanged.
lukaszad1485da72016-11-01 21:49:461034 // DictionaryValue::From is the equivalent for std::unique_ptr conversions.
Daniel Cheng619653b2022-02-17 18:33:121035 //
1036 // DEPRECATED: prefer direct use `base::Value::Dict` where possible, or
1037 // `GetIfDict()` otherwise.
jdoerrie8e945542017-02-17 13:54:491038 bool GetAsDictionary(DictionaryValue** out_value);
1039 bool GetAsDictionary(const DictionaryValue** out_value) const;
[email protected]2f03f532013-07-17 08:43:331040 // Note: Do not add more types. See the file-level comment above for why.
initial.commitd7cae122008-07-26 21:49:381041
1042 // This creates a deep copy of the entire Value tree, and returns a pointer
jdoerrie05eb3162017-02-01 10:36:561043 // to the copy. The caller gets ownership of the copy, of course.
[email protected]16f47e082011-01-18 02:16:591044 // Subclasses return their own type directly in their overrides;
1045 // this works because C++ supports covariant return types.
jdoerriee964d9a2017-04-05 06:44:171046 // TODO(crbug.com/646113): Delete this and migrate callsites.
Daniel Cheng619653b2022-02-17 18:33:121047 //
1048 // DEPRECATED: prefer `Value::Clone()`.
dcheng093de9b2016-04-04 21:25:511049 std::unique_ptr<Value> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381050
jdoerrie5c1cee112017-03-28 17:52:001051 // Comparison operators so that Values can easily be used with standard
1052 // library algorithms and associative containers.
1053 BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
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
Daniel Cheng0b0b6752022-05-25 02:59:481060 BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs);
1061 friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; }
1062 friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); }
1063 friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); }
Daniel Cheng6b621cf2022-06-02 02:42:021064 template <typename T>
1065 friend bool operator==(const Value& lhs, const T* rhs) = delete;
1066 template <typename T>
1067 friend bool operator==(const T* lhs, const Value& rhs) = delete;
1068 template <typename T>
1069 friend bool operator!=(const Value& lhs, const T* rhs) = delete;
1070 template <typename T>
1071 friend bool operator!=(const T* lhs, const Value& rhs) = delete;
Daniel Cheng0b0b6752022-05-25 02:59:481072 BASE_EXPORT friend bool operator==(const Value& lhs, int rhs);
1073 friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; }
1074 friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); }
1075 friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); }
1076 BASE_EXPORT friend bool operator==(const Value& lhs, double rhs);
1077 friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; }
1078 friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); }
1079 friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); }
Daniel Cheng6b621cf2022-06-02 02:42:021080 // Note: StringPiece16 overload intentionally omitted: Value internally stores
1081 // strings as UTF-8. While it is possible to implement a comparison operator
1082 // that would not require first creating a new UTF-8 string from the UTF-16
1083 // string argument, it is simpler to just not implement it at all for a rare
1084 // use case.
Daniel Cheng0b0b6752022-05-25 02:59:481085 BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs);
1086 friend bool operator==(StringPiece lhs, const Value& rhs) {
1087 return rhs == lhs;
1088 }
1089 friend bool operator!=(const Value& lhs, StringPiece rhs) {
1090 return !(lhs == rhs);
1091 }
1092 friend bool operator!=(StringPiece lhs, const Value& rhs) {
1093 return !(lhs == rhs);
1094 }
Daniel Cheng6b621cf2022-06-02 02:42:021095 friend bool operator==(const Value& lhs, const char* rhs) {
1096 return lhs == StringPiece(rhs);
1097 }
1098 friend bool operator==(const char* lhs, const Value& rhs) {
1099 return rhs == lhs;
1100 }
1101 friend bool operator!=(const Value& lhs, const char* rhs) {
1102 return !(lhs == rhs);
1103 }
1104 friend bool operator!=(const char* lhs, const Value& rhs) {
1105 return !(lhs == rhs);
1106 }
1107 friend bool operator==(const Value& lhs, const std::string& rhs) {
1108 return lhs == StringPiece(rhs);
1109 }
1110 friend bool operator==(const std::string& lhs, const Value& rhs) {
1111 return rhs == lhs;
1112 }
1113 friend bool operator!=(const Value& lhs, const std::string& rhs) {
1114 return !(lhs == rhs);
1115 }
1116 friend bool operator!=(const std::string& lhs, const Value& rhs) {
1117 return !(lhs == rhs);
1118 }
Daniel Cheng0b0b6752022-05-25 02:59:481119 // Note: Blob support intentionally omitted as an experiment for potentially
1120 // wholly removing Blob support from Value itself in the future.
1121 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs);
1122 friend bool operator==(const Value::Dict& lhs, const Value& rhs) {
1123 return rhs == lhs;
1124 }
1125 friend bool operator!=(const Value& lhs, const Value::Dict& rhs) {
1126 return !(lhs == rhs);
1127 }
1128 friend bool operator!=(const Value::Dict& lhs, const Value& rhs) {
1129 return !(lhs == rhs);
1130 }
1131 BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs);
1132 friend bool operator==(const Value::List& lhs, const Value& rhs) {
1133 return rhs == lhs;
1134 }
1135 friend bool operator!=(const Value& lhs, const Value::List& rhs) {
1136 return !(lhs == rhs);
1137 }
1138 friend bool operator!=(const Value::List& lhs, const Value& rhs) {
1139 return !(lhs == rhs);
1140 }
1141
Eric Secklerf6c544f2020-06-02 10:49:211142 // Estimates dynamic memory usage. Requires tracing support
1143 // (enable_base_tracing gn flag), otherwise always returns 0. See
1144 // base/trace_event/memory_usage_estimator.h for more info.
Alexander Yashkinab504e72017-11-30 11:54:451145 size_t EstimateMemoryUsage() const;
1146
Alan Cutter2dd83032020-12-08 21:55:001147 // Serializes to a string for logging and debug purposes.
1148 std::string DebugString() const;
1149
Peter Kotwicz83a231372021-04-13 17:42:121150#if BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211151 // Write this object into a trace.
Alexander Timinbebb2002021-04-20 15:42:241152 void WriteIntoTrace(perfetto::TracedValue) const;
Peter Kotwicz83a231372021-04-13 17:42:121153#endif // BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211154
Daniel Cheng8ac305b2022-02-17 00:05:111155 template <typename Visitor>
1156 auto Visit(Visitor&& visitor) const {
1157 return absl::visit(std::forward<Visitor>(visitor), data_);
1158 }
1159
jdoerrie8e945542017-02-17 13:54:491160 protected:
Matt Menke06842489d2022-07-22 00:04:331161 // TODO(https://crbug.com/1187091): Once deprecated list methods and ListView
1162 // have been removed, make this a private member of List.
1163 using ListStorage = DeprecatedListStorage;
1164
Jan Wilken Dörrie79d022142020-08-19 18:18:321165 // Checked convenience accessors for dict and list.
Daniel Chenga367fe52022-02-15 18:08:481166 const LegacyDictStorage& dict() const { return GetDict().storage_; }
1167 LegacyDictStorage& dict() { return GetDict().storage_; }
1168 const ListStorage& list() const { return GetList().storage_; }
1169 ListStorage& list() { return GetList().storage_; }
Jan Wilken Dörrie79d022142020-08-19 18:18:321170
Jan Wilken Dörrief961a372020-11-02 20:30:341171 // Internal constructors, allowing the simplify the implementation of Clone().
1172 explicit Value(const LegacyDictStorage& storage);
1173 explicit Value(LegacyDictStorage&& storage) noexcept;
1174
Jan Wilken Dörrie79d022142020-08-19 18:18:321175 private:
Daniel Cheng8ac305b2022-02-17 00:05:111176 // For access to DoubleStorage.
1177 friend class ValueView;
1178
David 'Digit' Turner2f287312019-04-03 14:32:091179 // Special case for doubles, which are aligned to 8 bytes on some
1180 // 32-bit architectures. In this case, a simple declaration as a
1181 // double member would make the whole union 8 byte-aligned, which
1182 // would also force 4 bytes of wasted padding space before it in
1183 // the Value layout.
David 'Digit' Turner806dedb82019-03-06 17:43:111184 //
David 'Digit' Turner2f287312019-04-03 14:32:091185 // To override this, store the value as an array of 32-bit integers, and
1186 // perform the appropriate bit casts when reading / writing to it.
Daniel Cheng6b621cf2022-06-02 02:42:021187 class BASE_EXPORT DoubleStorage {
Daniel Cheng782d2ba32022-02-16 19:40:291188 public:
1189 explicit DoubleStorage(double v);
1190 DoubleStorage(const DoubleStorage&) = default;
1191 DoubleStorage& operator=(const DoubleStorage&) = default;
1192
Daniel Cheng8ac305b2022-02-17 00:05:111193 // Provide an implicit conversion to double to simplify the use of visitors
1194 // with `Value::Visit()`. Otherwise, visitors would need a branch for
1195 // handling `DoubleStorage` like:
1196 //
1197 // value.Visit([] (const auto& member) {
1198 // using T = std::decay_t<decltype(member)>;
1199 // if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
1200 // SomeFunction(double{member});
1201 // } else {
1202 // SomeFunction(member);
1203 // }
1204 // });
Peter Kastingcc88ac052022-05-03 09:58:011205 operator double() const { return base::bit_cast<double>(v_); }
Daniel Cheng782d2ba32022-02-16 19:40:291206
1207 private:
1208 friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111209 return double{lhs} == double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291210 }
1211
1212 friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1213 return !(lhs == rhs);
1214 }
1215
1216 friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111217 return double{lhs} < double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291218 }
1219
1220 friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1221 return rhs < lhs;
1222 }
1223
1224 friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1225 return !(rhs < lhs);
1226 }
1227
1228 friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1229 return !(lhs < rhs);
1230 }
1231
1232 alignas(4) std::array<char, sizeof(double)> v_;
1233 };
David 'Digit' Turner2f287312019-04-03 14:32:091234
Jan Wilken Dörrie79d022142020-08-19 18:18:321235 // Internal constructors, allowing the simplify the implementation of Clone().
1236 explicit Value(absl::monostate);
1237 explicit Value(DoubleStorage storage);
jdoerrie8e945542017-02-17 13:54:491238
Jan Wilken Dörrie79d022142020-08-19 18:18:321239 absl::variant<absl::monostate,
1240 bool,
1241 int,
1242 DoubleStorage,
1243 std::string,
1244 BlobStorage,
Daniel Chenga367fe52022-02-15 18:08:481245 Dict,
1246 List>
Jan Wilken Dörrie79d022142020-08-19 18:18:321247 data_;
initial.commitd7cae122008-07-26 21:49:381248};
1249
[email protected]9e4cda7332010-07-31 04:56:141250// DictionaryValue provides a key-value dictionary with (optional) "path"
1251// parsing for recursive access; see the comment at the top of the file. Keys
Gabriel Charetted7c00cbe2021-05-14 20:05:531252// are std::string's and should be UTF-8 encoded.
Daniel Cheng619653b2022-02-17 18:33:121253//
1254// DEPRECATED: prefer `Value::Dict`.
[email protected]0bea7252011-08-05 15:34:001255class BASE_EXPORT DictionaryValue : public Value {
initial.commitd7cae122008-07-26 21:49:381256 public:
Gabriel Charetteb49d73a2021-05-05 20:05:591257 // Returns `value` if it is a dictionary, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511258 static std::unique_ptr<DictionaryValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541259
[email protected]3a3d47472010-07-15 21:03:541260 DictionaryValue();
Jan Wilken Dörrief961a372020-11-02 20:30:341261 explicit DictionaryValue(const LegacyDictStorage& in_dict);
1262 explicit DictionaryValue(LegacyDictStorage&& in_dict) noexcept;
[email protected]5cf906f82011-11-26 01:11:441263
initial.commitd7cae122008-07-26 21:49:381264 // Sets the Value associated with the given path starting from this object.
1265 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1266 // into the next DictionaryValue down. Obviously, "." can't be used
1267 // within a key, but there are no other restrictions on keys.
1268 // If the key at any step of the way doesn't exist, or exists but isn't
1269 // a DictionaryValue, a new DictionaryValue will be created and attached
Gabriel Charetteb49d73a2021-05-05 20:05:591270 // to the path in that location. `in_value` must be non-null.
jdoerrieb94e5422017-04-28 21:52:581271 // Returns a pointer to the inserted value.
Daniel Cheng619653b2022-02-17 18:33:121272 //
1273 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1274 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1275 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581276 Value* Set(StringPiece path, std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381277
1278 // Convenience forms of Set(). These methods will replace any existing
1279 // value at that path, even if it has a different type.
Daniel Cheng619653b2022-02-17 18:33:121280 //
1281 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1282 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1283 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581284 Value* SetBoolean(StringPiece path, bool in_value);
Daniel Cheng619653b2022-02-17 18:33:121285 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1286 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1287 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581288 Value* SetInteger(StringPiece path, int in_value);
Daniel Cheng619653b2022-02-17 18:33:121289 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1290 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1291 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581292 Value* SetDouble(StringPiece path, double in_value);
Daniel Cheng619653b2022-02-17 18:33:121293 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1294 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1295 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581296 Value* SetString(StringPiece path, StringPiece in_value);
Daniel Cheng619653b2022-02-17 18:33:121297 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1298 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1299 // otherwise.
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571300 Value* SetString(StringPiece path, const std::u16string& in_value);
Daniel Cheng619653b2022-02-17 18:33:121301 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1302 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1303 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581304 ListValue* SetList(StringPiece path, std::unique_ptr<ListValue> in_value);
[email protected]4dad9ad82009-11-25 20:47:521305
1306 // Like Set(), but without special treatment of '.'. This allows e.g. URLs to
1307 // be used as paths.
Daniel Cheng619653b2022-02-17 18:33:121308 //
1309 // DEPRECATED: prefer `Value::Dict::Set()`.
jdoerrieb94e5422017-04-28 21:52:581310 Value* SetWithoutPathExpansion(StringPiece key,
1311 std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381312
1313 // Gets the Value associated with the given path starting from this object.
1314 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1315 // into the next DictionaryValue down. If the path can be resolved
1316 // successfully, the value for the last key in the path will be returned
Gabriel Charetteb49d73a2021-05-05 20:05:591317 // through the `out_value` parameter, and the function will return true.
1318 // Otherwise, it will return false and `out_value` will be untouched.
initial.commitd7cae122008-07-26 21:49:381319 // Note that the dictionary always owns the value that's returned.
Gabriel Charetteb49d73a2021-05-05 20:05:591320 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121321 //
1322 // DEPRECATED: prefer `Value::Dict::Find()` (if the path only has one
1323 // component, i.e. has no dots), or `Value::Dict::FindByDottedPath()`
1324 // otherwise.
asvitkinedbd26533e2015-06-23 18:22:521325 bool Get(StringPiece path, const Value** out_value) const;
1326 bool Get(StringPiece path, Value** out_value);
initial.commitd7cae122008-07-26 21:49:381327
Gabriel Charetteb49d73a2021-05-05 20:05:591328 // These are convenience forms of `Get()`. The value will be retrieved
initial.commitd7cae122008-07-26 21:49:381329 // and the return value will be true if the path is valid and the value at
1330 // the end of the path can be returned in the form specified.
Gabriel Charetteb49d73a2021-05-05 20:05:591331 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121332 //
1333 // DEPRECATED: prefer `Value::Dict::FindInt()` (if the path only has one
1334 // component, i.e. has no dots), or `Value::Dict::FindIntByDottedPath()`
1335 // otherwise.
dcheng16d6f532016-08-25 16:07:111336 bool GetInteger(StringPiece path, int* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121337 // DEPRECATED: prefer `Value::Dict::FindString()` (if the path only has one
1338 // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
1339 // otherwise.
dcheng16d6f532016-08-25 16:07:111340 bool GetString(StringPiece path, std::string* out_value) const;
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571341 bool GetString(StringPiece path, std::u16string* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121342 // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
1343 // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
1344 // otherwise.
Jan Wilken Dörrie79d022142020-08-19 18:18:321345 bool GetDictionary(StringPiece path, const DictionaryValue** out_value) const;
asvitkinedbd26533e2015-06-23 18:22:521346 bool GetDictionary(StringPiece path, DictionaryValue** out_value);
Daniel Cheng619653b2022-02-17 18:33:121347 // DEPRECATED: prefer `Value::Dict::FindList()` (if the path only has one
1348 // component, i.e. has no dots), or `Value::Dict::FindListByDottedPath()`
1349 // otherwise.
dcheng16d6f532016-08-25 16:07:111350 bool GetList(StringPiece path, const ListValue** out_value) const;
1351 bool GetList(StringPiece path, ListValue** out_value);
initial.commitd7cae122008-07-26 21:49:381352
Gabriel Charetteb49d73a2021-05-05 20:05:591353 // Like `Get()`, but without special treatment of '.'. This allows e.g. URLs
1354 // to be used as paths.
Gabriel Charetteb49d73a2021-05-05 20:05:591355 // DEPRECATED, use `Value::FindDictKey(key)` instead.
[email protected]a61890e2012-07-27 22:27:111356 bool GetDictionaryWithoutPathExpansion(
dcheng16d6f532016-08-25 16:07:111357 StringPiece key,
[email protected]a61890e2012-07-27 22:27:111358 const DictionaryValue** out_value) const;
Gabriel Charetteb49d73a2021-05-05 20:05:591359 // DEPRECATED, use `Value::FindDictKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111360 bool GetDictionaryWithoutPathExpansion(StringPiece key,
[email protected]a61890e2012-07-27 22:27:111361 DictionaryValue** out_value);
Gabriel Charetteb49d73a2021-05-05 20:05:591362 // DEPRECATED, use `Value::FindListKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111363 bool GetListWithoutPathExpansion(StringPiece key,
[email protected]a61890e2012-07-27 22:27:111364 const ListValue** out_value) const;
Gabriel Charetteb49d73a2021-05-05 20:05:591365 // DEPRECATED, use `Value::FindListKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111366 bool GetListWithoutPathExpansion(StringPiece key, ListValue** out_value);
[email protected]4dad9ad82009-11-25 20:47:521367
Gabriel Charetteb49d73a2021-05-05 20:05:591368 // Makes a copy of `this` but doesn't include empty dictionaries and lists in
1369 // the copy. This never returns NULL, even if `this` itself is empty.
dcheng093de9b2016-04-04 21:25:511370 std::unique_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const;
[email protected]ec330b52009-12-02 00:20:321371
Gabriel Charetteb49d73a2021-05-05 20:05:591372 // Swaps contents with the `other` dictionary.
jdoerrie8e945542017-02-17 13:54:491373 void Swap(DictionaryValue* other);
[email protected]ec5263a2011-05-10 09:23:391374
[email protected]32c0e002011-11-08 21:26:411375 // This class provides an iterator over both keys and values in the
1376 // dictionary. It can't be used to modify the dictionary.
Daniel Cheng619653b2022-02-17 18:33:121377 //
1378 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1379 // instead.
[email protected]a34cc092012-08-10 12:45:351380 class BASE_EXPORT Iterator {
[email protected]32c0e002011-11-08 21:26:411381 public:
[email protected]a34cc092012-08-10 12:45:351382 explicit Iterator(const DictionaryValue& target);
vmpstre65942b2016-02-25 00:50:311383 Iterator(const Iterator& other);
[email protected]a8d94b42013-12-10 18:52:221384 ~Iterator();
[email protected]32c0e002011-11-08 21:26:411385
Lei Zhang10fce02f2021-05-14 18:45:081386 bool IsAtEnd() const { return it_ == target_.DictItems().end(); }
[email protected]32c0e002011-11-08 21:26:411387 void Advance() { ++it_; }
1388
1389 const std::string& key() const { return it_->first; }
Lei Zhang10fce02f2021-05-14 18:45:081390 const Value& value() const { return it_->second; }
[email protected]32c0e002011-11-08 21:26:411391
1392 private:
1393 const DictionaryValue& target_;
Lei Zhang10fce02f2021-05-14 18:45:081394 detail::const_dict_iterator it_;
[email protected]32c0e002011-11-08 21:26:411395 };
1396
Daniel Cheng619653b2022-02-17 18:33:121397 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerriee964d9a2017-04-05 06:44:171398 // TODO(crbug.com/646113): Delete this and migrate callsites.
jdoerrie8e945542017-02-17 13:54:491399 DictionaryValue* DeepCopy() const;
Daniel Cheng619653b2022-02-17 18:33:121400 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerried4b852612017-06-06 11:48:431401 // TODO(crbug.com/646113): Delete this and migrate callsites.
dcheng093de9b2016-04-04 21:25:511402 std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381403};
1404
1405// This type of Value represents a list of other Value values.
Daniel Cheng619653b2022-02-17 18:33:121406//
1407// DEPRECATED: prefer `base::Value::List`.
[email protected]0bea7252011-08-05 15:34:001408class BASE_EXPORT ListValue : public Value {
initial.commitd7cae122008-07-26 21:49:381409 public:
Jan Wilken Dörrie46992f022020-02-20 11:25:471410 using const_iterator = ListView::const_iterator;
1411 using iterator = ListView::iterator;
[email protected]a502bbe72011-01-07 18:06:451412
Gabriel Charetteb49d73a2021-05-05 20:05:591413 // Returns `value` if it is a list, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511414 static std::unique_ptr<ListValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541415
[email protected]3a3d47472010-07-15 21:03:541416 ListValue();
initial.commitd7cae122008-07-26 21:49:381417
initial.commitd7cae122008-07-26 21:49:381418 // Appends a Value to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:121419 // DEPRECATED: prefer `Value::List::Append()`.
1420 using Value::Append;
Daniel Chengedfa5202022-04-15 00:09:591421 // DEPRECATED: prefer `Value::List::Append()`. Provided to simplify
1422 // incremental migration and intentionally only defined on ListValue and not
1423 // Value.
1424 void Append(base::Value::Dict in_dict);
1425 void Append(base::Value::List in_list);
initial.commitd7cae122008-07-26 21:49:381426
Gabriel Charetteb49d73a2021-05-05 20:05:591427 // Swaps contents with the `other` list.
Daniel Cheng619653b2022-02-17 18:33:121428 //
1429 // DEPRECATED: prefer `base::Value::List` + `std::swap()`.
jdoerrie8e945542017-02-17 13:54:491430 void Swap(ListValue* other);
[email protected]8b8e7c92010-08-19 18:05:561431
Daniel Cheng619653b2022-02-17 18:33:121432 // Iteration: Use a range-based for loop over `base::Value::List` directly
1433 // instead.
initial.commitd7cae122008-07-26 21:49:381434};
1435
Daniel Cheng8ac305b2022-02-17 00:05:111436// Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
1437// serialization methods without having to clone the contents and transfer
1438// ownership of the clone to a `Value` wrapper object.
1439//
1440// Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
1441// underlying object that is passed by reference (i.e. `std::string`,
1442// `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
1443// live as long as there is a `ValueView` referencing it.
1444//
1445// While it might be nice to just use the `absl::variant` type directly, the
1446// need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
1447// `std::reference_wrapper` both support implicit construction, but C++ only
1448// allows at most one user-defined conversion in an implicit conversion
1449// sequence. If this adapter and its implicit constructors did not exist,
1450// callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
1451// `Value::List` to a function with a `ValueView` parameter.
1452class BASE_EXPORT GSL_POINTER ValueView {
1453 public:
Daniel Cheng6b621cf2022-06-02 02:42:021454 ValueView() = default;
Daniel Cheng8ac305b2022-02-17 00:05:111455 ValueView(bool value) : data_view_(value) {}
Daniel Cheng6b621cf2022-06-02 02:42:021456 template <typename T>
1457 ValueView(const T*) = delete;
Daniel Cheng8ac305b2022-02-17 00:05:111458 ValueView(int value) : data_view_(value) {}
1459 ValueView(double value)
1460 : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
Daniel Cheng6b621cf2022-06-02 02:42:021461 ValueView(StringPiece value) : data_view_(value) {}
1462 ValueView(const char* value) : ValueView(StringPiece(value)) {}
1463 ValueView(const std::string& value) : ValueView(StringPiece(value)) {}
1464 // Note: UTF-16 is intentionally not supported. ValueView is intended to be a
1465 // low-cost view abstraction, but Value internally represents strings as
1466 // UTF-8, so it would not be possible to implement this without allocating an
1467 // entirely new UTF-8 string.
Daniel Cheng8ac305b2022-02-17 00:05:111468 ValueView(const Value::BlobStorage& value) : data_view_(value) {}
1469 ValueView(const Value::Dict& value) : data_view_(value) {}
1470 ValueView(const Value::List& value) : data_view_(value) {}
1471 ValueView(const Value& value);
1472
Daniel Cheng6b621cf2022-06-02 02:42:021473 // This is the only 'getter' method provided as `ValueView` is not intended
1474 // to be a general replacement of `Value`.
Daniel Cheng8ac305b2022-02-17 00:05:111475 template <typename Visitor>
1476 auto Visit(Visitor&& visitor) const {
1477 return absl::visit(std::forward<Visitor>(visitor), data_view_);
1478 }
1479
1480 private:
1481 using ViewType =
1482 absl::variant<absl::monostate,
1483 bool,
1484 int,
1485 Value::DoubleStorage,
Daniel Cheng6b621cf2022-06-02 02:42:021486 StringPiece,
Daniel Cheng8ac305b2022-02-17 00:05:111487 std::reference_wrapper<const Value::BlobStorage>,
1488 std::reference_wrapper<const Value::Dict>,
1489 std::reference_wrapper<const Value::List>>;
1490
Daniel Cheng6b621cf2022-06-02 02:42:021491 public:
1492 using DoubleStorageForTest = Value::DoubleStorage;
1493 const ViewType& data_view_for_test() const { return data_view_; }
1494
1495 private:
Daniel Cheng8ac305b2022-02-17 00:05:111496 ViewType data_view_;
1497};
1498
prashhir54a994502015-03-05 09:30:571499// This interface is implemented by classes that know how to serialize
1500// Value objects.
[email protected]0bea7252011-08-05 15:34:001501class BASE_EXPORT ValueSerializer {
initial.commitd7cae122008-07-26 21:49:381502 public:
[email protected]3a3d47472010-07-15 21:03:541503 virtual ~ValueSerializer();
[email protected]abb9d0c2008-08-06 15:46:591504
Daniel Cheng8ac305b2022-02-17 00:05:111505 virtual bool Serialize(ValueView root) = 0;
prashhir54a994502015-03-05 09:30:571506};
1507
1508// This interface is implemented by classes that know how to deserialize Value
1509// objects.
1510class BASE_EXPORT ValueDeserializer {
1511 public:
1512 virtual ~ValueDeserializer();
initial.commitd7cae122008-07-26 21:49:381513
1514 // This method deserializes the subclass-specific format into a Value object.
[email protected]b4cebf82008-12-29 19:59:081515 // If the return value is non-NULL, the caller takes ownership of returned
Nigel Tao410788e2020-06-24 07:12:271516 // Value.
1517 //
Gabriel Charetteb49d73a2021-05-05 20:05:591518 // If the return value is nullptr, and if `error_code` is non-nullptr,
1519 // `*error_code` will be set to an integer value representing the underlying
Nigel Tao410788e2020-06-24 07:12:271520 // error. See "enum ErrorCode" below for more detail about the integer value.
1521 //
Gabriel Charetteb49d73a2021-05-05 20:05:591522 // If `error_message` is non-nullptr, it will be filled in with a formatted
[email protected]ba399672010-04-06 15:42:391523 // error message including the location of the error if appropriate.
dcheng093de9b2016-04-04 21:25:511524 virtual std::unique_ptr<Value> Deserialize(int* error_code,
Nigel Tao410788e2020-06-24 07:12:271525 std::string* error_message) = 0;
1526
1527 // The integer-valued error codes form four groups:
1528 // - The value 0 means no error.
1529 // - Values between 1 and 999 inclusive mean an error in the data (i.e.
1530 // content). The bytes being deserialized are not in the right format.
1531 // - Values 1000 and above mean an error in the metadata (i.e. context). The
1532 // file could not be read, the network is down, etc.
1533 // - Negative values are reserved.
Caitlin Fischeraac06dc2021-12-17 00:21:321534 //
1535 // These values are persisted to logs. Entries should not be renumbered and
1536 // numeric values should never be reused.
Nigel Tao410788e2020-06-24 07:12:271537 enum ErrorCode {
1538 kErrorCodeNoError = 0,
1539 // kErrorCodeInvalidFormat is a generic error code for "the data is not in
1540 // the right format". Subclasses of ValueDeserializer may return other
1541 // values for more specific errors.
1542 kErrorCodeInvalidFormat = 1,
1543 // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
1544 // range of metadata errors.
1545 kErrorCodeFirstMetadataError = 1000,
1546 };
1547
Gabriel Charetteb49d73a2021-05-05 20:05:591548 // The `error_code` argument can be one of the ErrorCode values, but it is
Nigel Tao410788e2020-06-24 07:12:271549 // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
1550 // can define their own error code values.
1551 static inline bool ErrorCodeIsDataError(int error_code) {
1552 return (kErrorCodeInvalidFormat <= error_code) &&
1553 (error_code < kErrorCodeFirstMetadataError);
1554 }
initial.commitd7cae122008-07-26 21:49:381555};
1556
Daniel Chenga367fe52022-02-15 18:08:481557// Stream operator so Values can be pretty printed by gtest.
[email protected]e4ef8312012-09-12 03:39:351558BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
Daniel Chenga367fe52022-02-15 18:08:481559BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1560 const Value::Dict& dict);
1561BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1562 const Value::List& list);
[email protected]e4ef8312012-09-12 03:39:351563
Daniel Chenga367fe52022-02-15 18:08:481564// Hints for DictionaryValue and ListValue; otherwise, gtest tends to prefer the
1565// default template implementation over an upcast to Value.
[email protected]ea0ec052013-04-16 09:04:021566BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
[email protected]ea0ec052013-04-16 09:04:021567 const DictionaryValue& value) {
1568 return out << static_cast<const Value&>(value);
1569}
1570
1571BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
1572 const ListValue& value) {
1573 return out << static_cast<const Value&>(value);
1574}
1575
jdoerriedc72ee942016-12-07 15:43:281576// Stream operator so that enum class Types can be used in log statements.
1577BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1578 const Value::Type& type);
1579
[email protected]f3a1c642011-07-12 19:15:031580} // namespace base
1581
[email protected]101d5422008-09-26 20:22:421582#endif // BASE_VALUES_H_