blob: ddb8aa10e3ac37716eb982d13e7f2495f77cf530 [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>
dcheng093de9b2016-04-04 21:25:5114#include <memory>
[email protected]8e50b602009-03-03 22:59:4315#include <string>
[email protected]c014f2b32013-09-03 23:29:1216#include <utility>
initial.commitd7cae122008-07-26 21:49:3817#include <vector>
18
[email protected]0bea7252011-08-05 15:34:0019#include "base/base_export.h"
Daniel Cheng782d2ba32022-02-16 19:40:2920#include "base/bit_cast.h"
Daniel Cheng8ac305b2022-02-17 00:05:1121#include "base/compiler_specific.h"
Jan Wilken Dörrie7e7a9792019-10-15 14:42:0522#include "base/containers/checked_iterators.h"
Jan Wilken Dörrie8d9034f12019-11-28 14:48:5723#include "base/containers/checked_range.h"
Lei Zhanga1209af2021-06-26 03:26:2424#include "base/containers/cxx20_erase_vector.h"
mkwstcd8067b2017-04-11 06:52:2125#include "base/containers/flat_map.h"
jdoerriecd022242017-08-23 08:38:2726#include "base/containers/span.h"
asvitkinedbd26533e2015-06-23 18:22:5227#include "base/strings/string_piece.h"
Alexander Timine68aeb32021-04-11 23:06:2128#include "base/trace_event/base_tracing_forward.h"
jdoerrie44efa9d2017-07-14 14:47:2029#include "base/value_iterators.h"
Anton Bikineev7dd58ad2021-05-18 01:01:3930#include "third_party/abseil-cpp/absl/types/optional.h"
Jan Wilken Dörrie79d022142020-08-19 18:18:3231#include "third_party/abseil-cpp/absl/types/variant.h"
initial.commitd7cae122008-07-26 21:49:3832
[email protected]f3a1c642011-07-12 19:15:0333namespace base {
34
initial.commitd7cae122008-07-26 21:49:3835class DictionaryValue;
36class ListValue;
37
Daniel Chenga367fe52022-02-15 18:08:4838// The `Value` class is a variant type can hold one of the following types:
39// - null
40// - bool
41// - int
42// - double
43// - string (internally UTF8-encoded)
44// - binary data (i.e. a blob)
45// - dictionary of string keys to `Value`s
46// - list of `Value`s
[email protected]2f03f532013-07-17 08:43:3347//
Daniel Chenga367fe52022-02-15 18:08:4848// With the exception of binary blobs, `Value` is intended to be the C++ version
49// of data types that can be represented in JSON.
Brett Wilson4bef8ee2017-09-01 20:11:4950//
Daniel Chenga367fe52022-02-15 18:08:4851// Warning: blob support may be removed in the future.
52//
53// ## Usage
54//
55// Do not use `Value` if a more specific type would be more appropriate. For
56// example, a function that only accepts dictionary values should have a
57// `base::Value::Dict` parameter, not a `base::Value` parameter.
58//
59// Construction:
60//
61// `Value` is directly constructible from `bool`, `int`, `double`, binary blobs
62// (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`,
63// `Value::Dict`, and `Value::List`.
64//
65// Copying:
66//
67// `Value` does not support C++ copy semantics to make it harder to accidentally
68// copy large values. Instead, use `Clone()` to manually create a deep copy.
69//
70// Reading:
71//
72// `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct
73// subtype before returning the contained value. `bool`, `int`, `double` are
74// returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
75// are returned by reference.
76//
77// `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
78// the `Value` does not have the correct subtype; otherwise, returns the value
79// wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
80// (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
81//
82// Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
83// when the subtype is `Value::Type::INT`. In that case, the stored value is
84// coerced to a double before being returned.
85//
86// Assignment:
87//
88// It is not possible to directly assign `bool`, `int`, et cetera to a `Value`.
89// Instead, wrap the underlying type in `Value` before assigning.
90//
91// ## Dictionaries and Lists
92//
93// `Value` provides the `Value::Dict` and `Value::List` container types for
94// working with dictionaries and lists of values respectively, rather than
95// exposing the underlying container types directly. This allows the types to
96// provide convenient helpers for dictionaries and lists, as well as giving
97// greater flexibility for changing implementation details in the future.
98//
99// Both container types support enough STL-isms to be usable in range-based for
100// loops and generic operations such as those from <algorithm>.
101//
102// Dictionaries support:
103// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
104// `contains()`, `clear()`, `erase()`: Identical to the STL container
105// equivalents, with additional safety checks, e.g. iterators will
106// `CHECK()` if `end()` is dereferenced.
107//
108// - `Clone()`: Create a deep copy.
109// - `Merge()`: Merge another dictionary into this dictionary.
110// - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key
111// is not present.
112// - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
113// `Value` also has the correct subtype. Same return semantics as
114// `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
115// `nullptr` if the key is not present or the value has the wrong subtype.
116// - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
117// of the subtypes that `Value` can hold.
118// - `Remove()`: Remove the key from this dictionary, if present.
119// - `Extract()`: If the key is present in the dictionary, removes the key from
120// the dictionary and transfers ownership of `Value` to the caller.
121// Otherwise, returns `absl::nullopt`.
122//
123// Dictionaries also support an additional set of helper methods that operate on
124// "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
125// and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming
126// intermediate nested dictionaries, separating the components of the path using
127// '.' characters. For example, finding a string path on a `Value::Dict` using
128// the dotted path:
129//
130// "aaa.bbb.ccc"
131//
132// Will first look for a `Value::Type::DICT` associated with the key "aaa", then
133// another `Value::Type::DICT` under the "aaa" dict associated with the
134// key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated
135// with the key "ccc".
136//
Daniel Cheng619653b2022-02-17 18:33:12137// If a path only has one component (i.e. has no dots), please use the regular,
138// non-path APIs.
139//
Daniel Chenga367fe52022-02-15 18:08:48140// Lists support:
141// - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
Daniel Chengc9ab0ef2022-02-18 02:34:07142// `front()`, `back()`, `reserve()`, `operator[]`, `clear()`, `erase()`:
143// Identical to the STL container equivalents, with additional safety
144// checks, e.g. `operator[]` will `CHECK()` if the index is out of range.
Daniel Chenga367fe52022-02-15 18:08:48145// - `Clone()`: Create a deep copy.
146// - `Append()`: Append a value to the end of the list. Accepts `Value` or any
147// of the subtypes that `Value` can hold.
148// - `Insert()`: Insert a `Value` at a specified point in the list.
149// - `EraseValue()`: Erases all matching `Value`s from the list.
150// - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the
151// list.
152//
153// ## Refactoring Notes
154//
155// `Value` was originally implemented as a class hierarchy, with a `Value` base
156// class, and a leaf class for each of the different types of `Value` subtypes.
Brett Wilson4bef8ee2017-09-01 20:11:49157// https://docs.google.com/document/d/1uDLu5uTRlCWePxQUEHc8yNQdEoE1BDISYdpggWEABnw
Daniel Chenga367fe52022-02-15 18:08:48158// proposed an overhaul of the `Value` API that has now largely been
159// implemented, though there remains a significant amount of legacy code that is
160// still being migrated as part of the code health migration.
Brett Wilson4bef8ee2017-09-01 20:11:49161//
162// OLD WAY:
163//
164// std::unique_ptr<base::Value> GetFoo() {
165// std::unique_ptr<DictionaryValue> dict;
Daniel Chenga367fe52022-02-15 18:08:48166// dict->SetString("mykey", "foo");
Brett Wilson4bef8ee2017-09-01 20:11:49167// return dict;
168// }
169//
Brett Wilson4bef8ee2017-09-01 20:11:49170// NEW WAY:
171//
172// base::Value GetFoo() {
Daniel Chenga367fe52022-02-15 18:08:48173// base::Value::Dict dict;
Scott Haseley5fd36262022-03-04 19:35:11174// dict.Set("mykey", "abc");
Daniel Chenga367fe52022-02-15 18:08:48175// return base::Value(std::move(dict));
Brett Wilson4bef8ee2017-09-01 20:11:49176// }
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04177//
Daniel Chenga367fe52022-02-15 18:08:48178// To avoid losing type information with the new variant-based design, migration
179// off the deprecated types should use more specific subtypes where possible:
Jan Wilken Dörriecf4ce5522020-10-27 14:41:04180//
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49181// OLD WAY:
182//
183// void AlwaysTakesList(std::unique_ptr<base::ListValue> list);
184// void AlwaysTakesDict(std::unique_ptr<base::DictionaryValue> dict);
185//
Daniel Chenga367fe52022-02-15 18:08:48186// DEPRECATED (PREVIOUS) WAY:
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49187//
188// void AlwaysTakesList(std::vector<base::Value> list);
Daniel Chenga367fe52022-02-15 18:08:48189// void AlwaysTakesListAlternative1(base::Value::ConstListView list);
190// void AlwaysTakesListAlternative2(base::Value::ListView& list);
191// void AlwaysTakesListAlterantive3(base::Value::ListStorage);
Jan Wilken Dörrie2a06d6e92020-11-09 09:32:49192// void AlwaysTakesDict(base::flat_map<std::string, base::Value> dict);
Daniel Chenga367fe52022-02-15 18:08:48193// void AlwaysTakesDictAlternative(base::Value::DictStorage);
Daniel Cheng60e6b2d2022-02-05 01:08:46194//
195// NEW WAY:
196//
Daniel Chenga367fe52022-02-15 18:08:48197// void AlwaysTakesList(base::Value::List list);
198// void AlwaysTakesDict(base::Value::Dict dict);
Daniel Cheng60e6b2d2022-02-05 01:08:46199//
Daniel Chenga367fe52022-02-15 18:08:48200// Migrating code may require conversions on API boundaries. If something seems
201// awkward/inefficient, please reach out to #code-health-rotation on Slack for
202// consultation: it is entirely possible that certain classes of APIs may be
203// missing due to an unrealized need.
Daniel Cheng8ac305b2022-02-17 00:05:11204class BASE_EXPORT GSL_OWNER Value {
initial.commitd7cae122008-07-26 21:49:38205 public:
jdoerrie9970f20e2018-07-20 21:41:18206 using BlobStorage = std::vector<uint8_t>;
Daniel Cheng773ce4502022-01-28 15:25:06207
208 using DeprecatedListStorage = std::vector<Value>;
209 using DeprecatedDictStorage = flat_map<std::string, Value>;
210 // TODO(https://crbug.com/1291666): Make these private.
211 using ListStorage = DeprecatedListStorage;
212 using DictStorage = DeprecatedDictStorage;
Jan Wilken Dörrief961a372020-11-02 20:30:34213
214 // Like `DictStorage`, but with std::unique_ptr in the mapped type. This is
215 // due to legacy reasons, and should be removed once no caller relies on
216 // stability of pointers anymore.
217 using LegacyDictStorage = flat_map<std::string, std::unique_ptr<Value>>;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57218
Daniel Cheng773ce4502022-01-28 15:25:06219 using DeprecatedListView = CheckedContiguousRange<ListStorage>;
220 using DeprecatedConstListView = CheckedContiguousConstRange<ListStorage>;
221 // TODO(https://crbug.com/1291666): Make these private.
222 using ListView = DeprecatedListView;
223 using ConstListView = DeprecatedConstListView;
Jan Wilken Dörrie8d9034f12019-11-28 14:48:57224
Daniel Chenga367fe52022-02-15 18:08:48225 class Dict;
226 class List;
227
Jose Dapena Paz7685422a2019-04-03 18:35:04228 enum class Type : unsigned char {
jdoerriedc72ee942016-12-07 15:43:28229 NONE = 0,
230 BOOLEAN,
231 INTEGER,
232 DOUBLE,
233 STRING,
234 BINARY,
Daniel Chenga367fe52022-02-15 18:08:48235 DICT,
236 // TODO(https://crbug.com/1291670): Deprecated and will be removed.
237 DICTIONARY = DICT,
jdoerriee1b1f3a2019-03-16 04:08:01238 LIST,
[email protected]2f03f532013-07-17 08:43:33239 // Note: Do not add more types. See the file-level comment above for why.
[email protected]a502bbe72011-01-07 18:06:45240 };
241
Lei Zhang30895d52017-10-23 19:14:46242 // Adaptors for converting from the old way to the new way and vice versa.
243 static Value FromUniquePtrValue(std::unique_ptr<Value> val);
244 static std::unique_ptr<Value> ToUniquePtrValue(Value val);
Lei Zhang8c1432b2019-10-08 18:48:54245 static const DictionaryValue& AsDictionaryValue(const Value& val);
246 static const ListValue& AsListValue(const Value& val);
Lei Zhang30895d52017-10-23 19:14:46247
Jan Wilken Dörrie79d022142020-08-19 18:18:32248 Value() noexcept;
jdoerriecc9f5732017-08-23 14:12:30249
Daniel Chenga367fe52022-02-15 18:08:48250 Value(Value&&) noexcept;
251 Value& operator=(Value&&) noexcept;
jdoerriecc9f5732017-08-23 14:12:30252
Daniel Chenga367fe52022-02-15 18:08:48253 // Deleted to prevent accidental copying.
David Bienvenu5f4d4f02020-09-27 16:55:03254 Value(const Value&) = delete;
255 Value& operator=(const Value&) = delete;
jdoerrie05eb3162017-02-01 10:36:56256
Daniel Chenga367fe52022-02-15 18:08:48257 // Creates a deep copy of this value.
258 Value Clone() const;
259
260 // Creates a `Value` of `type`. The data of the corresponding type will be
261 // default constructed.
262 explicit Value(Type type);
263
264 // Constructor for `Value::Type::BOOLEAN`.
265 explicit Value(bool value);
266
267 // Prevent pointers from implicitly converting to bool. Another way to write
268 // this would be to template the bool constructor and use SFINAE to only allow
269 // use if `std::is_same_v<T, bool>` is true, but this has surprising behavior
270 // with range-based for loops over a `std::vector<bool>` (which will
271 // unintuitively match the int overload instead).
272 //
273 // The `const` is load-bearing; otherwise, a `char*` argument would prefer the
274 // deleted overload due to requiring a qualification conversion.
275 template <typename T>
276 explicit Value(const T*) = delete;
277
278 // Constructor for `Value::Type::INT`.
279 explicit Value(int value);
280
281 // Constructor for `Value::Type::DOUBLE`.
282 explicit Value(double value);
283
284 // Constructors for `Value::Type::STRING`.
285 explicit Value(StringPiece value);
286 explicit Value(StringPiece16 value);
287 // `char*` and `char16_t*` are needed to provide a more specific overload than
288 // the deleted `const T*` overload above.
289 explicit Value(const char* value);
290 explicit Value(const char16_t* value);
291 // `std::string&&` allows for efficient move construction.
292 explicit Value(std::string&& value) noexcept;
293
294 // Constructors for `Value::Type::BINARY`.
295 explicit Value(const std::vector<char>& value);
296 explicit Value(base::span<const uint8_t> value);
297 explicit Value(BlobStorage&& value) noexcept;
298
299 // Constructor for `Value::Type::DICT`.
300 explicit Value(Dict&& value) noexcept;
301
302 // Constructor for `Value::Type::LIST`.
303 explicit Value(List&& value) noexcept;
304
Daniel Cheng619653b2022-02-17 18:33:12305 // DEPRECATED: prefer `Value(Dict&&)`.
Daniel Chenga367fe52022-02-15 18:08:48306 explicit Value(const DictStorage& value);
307 explicit Value(DictStorage&& value);
308
Daniel Cheng619653b2022-02-17 18:33:12309 // DEPRECATED: prefer `Value(List&&)`.
Daniel Chenga367fe52022-02-15 18:08:48310 explicit Value(span<const Value> value);
311 explicit Value(ListStorage&& value) noexcept;
312
jdoerrie8e945542017-02-17 13:54:49313 ~Value();
jdoerrie05eb3162017-02-01 10:36:56314
Gabriel Charetteb49d73a2021-05-05 20:05:59315 // Returns the name for a given `type`.
thestig61709242016-07-19 00:39:30316 static const char* GetTypeName(Type type);
317
initial.commitd7cae122008-07-26 21:49:38318 // Returns the type of the value stored by the current Value object.
Jan Wilken Dörrie79d022142020-08-19 18:18:32319 Type type() const { return static_cast<Type>(data_.index()); }
initial.commitd7cae122008-07-26 21:49:38320
321 // Returns true if the current object represents a given type.
jdoerriecc9f5732017-08-23 14:12:30322 bool is_none() const { return type() == Type::NONE; }
jdoerrie05eb3162017-02-01 10:36:56323 bool is_bool() const { return type() == Type::BOOLEAN; }
324 bool is_int() const { return type() == Type::INTEGER; }
325 bool is_double() const { return type() == Type::DOUBLE; }
326 bool is_string() const { return type() == Type::STRING; }
327 bool is_blob() const { return type() == Type::BINARY; }
Daniel Chenga367fe52022-02-15 18:08:48328 bool is_dict() const { return type() == Type::DICT; }
jdoerrie05eb3162017-02-01 10:36:56329 bool is_list() const { return type() == Type::LIST; }
330
Daniel Chenga367fe52022-02-15 18:08:48331 // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
332 // otherwise. `bool`, `int`, and `double` are returned in a wrapped
333 // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
334 // pointer.
Anton Bikineev7dd58ad2021-05-18 01:01:39335 absl::optional<bool> GetIfBool() const;
336 absl::optional<int> GetIfInt() const;
Daniel Chenga367fe52022-02-15 18:08:48337 // Returns a non-null value for both `Value::Type::DOUBLE` and
338 // `Value::Type::INT`, converting the latter to a double.
Anton Bikineev7dd58ad2021-05-18 01:01:39339 absl::optional<double> GetIfDouble() const;
Jan Wilken Dörrie2e125622021-02-17 10:52:53340 const std::string* GetIfString() const;
Daniel Chenga367fe52022-02-15 18:08:48341 std::string* GetIfString();
Jan Wilken Dörrie2e125622021-02-17 10:52:53342 const BlobStorage* GetIfBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48343 const Dict* GetIfDict() const;
344 Dict* GetIfDict();
345 const List* GetIfList() const;
346 List* GetIfList();
Jan Wilken Dörrie2e125622021-02-17 10:52:53347
Daniel Chenga367fe52022-02-15 18:08:48348 // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a
349 // type mismatch. `bool`, `int`, and `double` are returned by value; blobs,
350 // `Value::Dict`, and `Value::List` are returned by reference.
jdoerrie05eb3162017-02-01 10:36:56351 bool GetBool() const;
352 int GetInt() const;
Daniel Chenga367fe52022-02-15 18:08:48353 // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`,
354 // converting the latter to a double.
355 double GetDouble() const;
jdoerrief38f37b2017-02-01 14:38:32356 const std::string& GetString() const;
Dominic Battre08cbe972019-07-31 03:57:19357 std::string& GetString();
jdoerrie5f12b6272017-04-18 10:22:41358 const BlobStorage& GetBlob() const;
Daniel Chenga367fe52022-02-15 18:08:48359 const Dict& GetDict() const;
360 Dict& GetDict();
361 const List& GetList() const;
362 List& GetList();
363
364 // Represents a dictionary of string keys to Values.
Daniel Cheng8ac305b2022-02-17 00:05:11365 class BASE_EXPORT GSL_OWNER Dict {
Daniel Chenga367fe52022-02-15 18:08:48366 public:
367 using iterator = detail::dict_iterator;
368 using const_iterator = detail::const_dict_iterator;
369
370 Dict();
371
372 Dict(Dict&&) noexcept;
373 Dict& operator=(Dict&&) noexcept;
374
375 // Deleted to prevent accidental copying.
376 Dict(const Dict&) = delete;
377 Dict& operator=(const Dict&) = delete;
378
379 ~Dict();
380
381 // TODO(dcheng): Probably need to allow construction from a pair of
382 // iterators for now due to the prevalence of DictStorage.
383
384 // Returns true if there are no entries in this dictionary and false
385 // otherwise.
386 bool empty() const;
387
388 // Returns the number of entries in this dictionary.
389 size_t size() const;
390
391 // Returns an iterator to the first entry in this dictionary.
392 iterator begin();
393 const_iterator begin() const;
394 const_iterator cbegin() const;
395
396 // Returns an iterator following the last entry in this dictionary. May not
397 // be dereferenced.
398 iterator end();
399 const_iterator end() const;
400 const_iterator cend() const;
401
402 // Returns true if `key` is an entry in this dictionary.
403 bool contains(base::StringPiece key) const;
404
405 // Removes all entries from this dictionary.
406 void clear();
407
408 // Removes the entry referenced by `pos` in this dictionary and returns an
409 // iterator to the entry following the removed entry.
410 iterator erase(iterator pos);
411 iterator erase(const_iterator pos);
412
413 // Creates a deep copy of this dictionary.
414 Dict Clone() const;
415
416 // Merges the entries from `dict` into this dictionary. If an entry with the
417 // same key exists in this dictionary and `dict`:
418 // - if both entries are dictionaries, they will be recursively merged
419 // - otherwise, the already-existing entry in this dictionary will be
420 // overwritten with the entry from `dict`.
421 void Merge(const Dict& dict);
422
423 // Finds the entry corresponding to `key` in this dictionary. Returns
424 // nullptr if there is no such entry.
425 const Value* Find(StringPiece key) const;
426 Value* Find(StringPiece key);
427
428 // Similar to `Find()` above, but returns `absl::nullopt`/`nullptr` if the
429 // type of the entry does not match. `bool`, `int`, and `double` are
430 // returned in a wrapped `absl::optional`; blobs, `Value::Dict`, and
431 // `Value::List` are returned by pointer.
432 absl::optional<bool> FindBool(StringPiece key) const;
433 absl::optional<int> FindInt(StringPiece key) const;
434 // Returns a non-null value for both `Value::Type::DOUBLE` and
435 // `Value::Type::INT`, converting the latter to a double.
436 absl::optional<double> FindDouble(StringPiece key) const;
437 const std::string* FindString(StringPiece key) const;
438 std::string* FindString(StringPiece key);
439 const BlobStorage* FindBlob(StringPiece key) const;
440 const Dict* FindDict(StringPiece key) const;
441 Dict* FindDict(StringPiece key);
442 const List* FindList(StringPiece key) const;
443 List* FindList(StringPiece key);
444
445 // Sets an entry with `key` and `value` in this dictionary, overwriting any
446 // existing entry with the same `key`. Returns a pointer to the set `value`.
447 Value* Set(StringPiece key, Value&& value);
448 Value* Set(StringPiece key, bool value);
449 template <typename T>
450 Value* Set(StringPiece, const T*) = delete;
451 Value* Set(StringPiece key, int value);
452 Value* Set(StringPiece key, double value);
453 Value* Set(StringPiece key, StringPiece value);
454 Value* Set(StringPiece key, StringPiece16 value);
455 Value* Set(StringPiece key, const char* value);
456 Value* Set(StringPiece key, const char16_t* value);
457 Value* Set(StringPiece key, std::string&& value);
458 Value* Set(StringPiece key, BlobStorage&& value);
459 Value* Set(StringPiece key, Dict&& value);
460 Value* Set(StringPiece key, List&& value);
461
462 // Removes the entry corresponding to `key` from this dictionary. Returns
463 // true if an entry was removed or false otherwise.
464 bool Remove(StringPiece key);
465
466 // Similar to `Remove()`, but returns the value corresponding to the removed
467 // entry or `absl::nullopt` otherwise.
468 absl::optional<Value> Extract(StringPiece key);
469
470 // Equivalent to the above methods but operating on paths instead of keys.
471 // A path is shorthand syntax for referring to a key nested inside
472 // intermediate dictionaries, with components delimited by ".". Paths may
473 // not be empty.
474 //
Daniel Cheng619653b2022-02-17 18:33:12475 // Prefer the non-path methods above when possible. Paths that have only one
476 // component (i.e. no dots in the path) should never use the path-based
477 // methods.
478 //
479 // Originally, the path-based APIs were the only way of specifying a key, so
480 // there are likely to be many legacy (and unnecessary) uses of the path
481 // APIs that do not actually require traversing nested dictionaries.
Daniel Chenga367fe52022-02-15 18:08:48482 const Value* FindByDottedPath(StringPiece path) const;
483 Value* FindByDottedPath(StringPiece path);
484
485 absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
486 absl::optional<int> FindIntByDottedPath(StringPiece path) const;
487 // Returns a non-null value for both `Value::Type::DOUBLE` and
488 // `Value::Type::INT`, converting the latter to a double.
489 absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
490 const std::string* FindStringByDottedPath(StringPiece path) const;
491 std::string* FindStringByDottedPath(StringPiece path);
492 const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
493 const Dict* FindDictByDottedPath(StringPiece path) const;
494 Dict* FindDictByDottedPath(StringPiece path);
495 const List* FindListByDottedPath(StringPiece path) const;
496 List* FindListByDottedPath(StringPiece path);
497
Daniel Cheng619653b2022-02-17 18:33:12498 // Creates a new entry with a dictionary for any non-last component that is
499 // missing an entry while performing the path traversal. Will fail if any
500 // non-last component of the path refers to an already-existing entry that
501 // is not a dictionary. Returns `nullptr` on failure.
Daniel Chenga367fe52022-02-15 18:08:48502 Value* SetByDottedPath(StringPiece path, Value&& value);
503 Value* SetByDottedPath(StringPiece path, bool value);
504 template <typename T>
505 Value* SetByDottedPath(StringPiece, const T*) = delete;
506 Value* SetByDottedPath(StringPiece path, int value);
507 Value* SetByDottedPath(StringPiece path, double value);
508 Value* SetByDottedPath(StringPiece path, StringPiece value);
509 Value* SetByDottedPath(StringPiece path, StringPiece16 value);
510 Value* SetByDottedPath(StringPiece path, const char* value);
511 Value* SetByDottedPath(StringPiece path, const char16_t* value);
512 Value* SetByDottedPath(StringPiece path, std::string&& value);
513 Value* SetByDottedPath(StringPiece path, BlobStorage&& value);
514 Value* SetByDottedPath(StringPiece path, Dict&& value);
515 Value* SetByDottedPath(StringPiece path, List&& value);
516
517 bool RemoveByDottedPath(StringPiece path);
518
519 absl::optional<Value> ExtractByDottedPath(StringPiece path);
520
Scott Haseleye51040782022-03-09 17:32:37521 // Serializes to a string for logging and debug purposes.
522 std::string DebugString() const;
523
Daniel Chenga367fe52022-02-15 18:08:48524 private:
525 BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs);
526 BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs);
527 BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs);
528 BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs);
529 BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs);
530 BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs);
531
532 // For legacy access to the internal storage type.
533 friend Value;
534
535 explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage);
536
537 flat_map<std::string, std::unique_ptr<Value>> storage_;
538 };
539
540 // Represents a list of Values.
Daniel Cheng8ac305b2022-02-17 00:05:11541 class BASE_EXPORT GSL_OWNER List {
Daniel Chenga367fe52022-02-15 18:08:48542 public:
543 using iterator = CheckedContiguousIterator<Value>;
544 using const_iterator = CheckedContiguousConstIterator<Value>;
545
546 List();
547
548 List(List&&) noexcept;
549 List& operator=(List&&) noexcept;
550
551 // Deleted to prevent accidental copying.
552 List(const List&) = delete;
553 List& operator=(const List&) = delete;
554
555 ~List();
556
557 // TODO(dcheng): Probably need to allow construction from a pair of
558 // iterators for now due to the prevalence of ListStorage now.
559
560 // Returns true if there are no values in this list and false otherwise.
561 bool empty() const;
562
563 // Returns the number of values in this list.
564 size_t size() const;
565
566 // Returns an iterator to the first value in this list.
567 iterator begin();
568 const_iterator begin() const;
569 const_iterator cbegin() const;
570
571 // Returns an iterator following the last value in this list. May not be
572 // dereferenced.
573 iterator end();
574 const_iterator end() const;
575 const_iterator cend() const;
576
Daniel Chengc9ab0ef2022-02-18 02:34:07577 // Returns a reference to the first value in the container. Fails with
578 // `CHECK()` if the list is empty.
579 const Value& front() const;
580 Value& front();
581
582 // Returns a reference to the last value in the container. Fails with
583 // `CHECK()` if the list is empty.
584 const Value& back() const;
585 Value& back();
586
587 // Increase the capacity of the backing container, but does not change
588 // the size. Assume all existing iterators will be invalidated.
589 void reserve(size_t capacity);
590
Daniel Chenga367fe52022-02-15 18:08:48591 // Returns a reference to the value at `index` in this list. Fails with a
592 // `CHECK()` if `index >= size()`.
593 const Value& operator[](size_t index) const;
594 Value& operator[](size_t index);
595
596 // Removes all value from this list.
597 void clear();
598
Daniel Chengc9ab0ef2022-02-18 02:34:07599 // Removes the value referenced by `pos` in this list and returns an
600 // iterator to the value following the removed value.
Daniel Chenga367fe52022-02-15 18:08:48601 iterator erase(iterator pos);
602 const_iterator erase(const_iterator pos);
603
604 // Creates a deep copy of this dictionary.
605 List Clone() const;
606
607 // Appends `value` to the end of this list.
608 void Append(Value&& value);
609 void Append(bool value);
610 template <typename T>
611 void Append(const T*) = delete;
612 void Append(int value);
613 void Append(double value);
614 void Append(StringPiece value);
615 void Append(StringPiece16 value);
616 void Append(const char* value);
617 void Append(const char16_t* value);
618 void Append(std::string&& value);
619 void Append(BlobStorage&& value);
620 void Append(Dict&& value);
621 void Append(List&& value);
622
623 // Inserts `value` before `pos` in this list. Returns an iterator to the
624 // inserted value.
625 // TODO(dcheng): Should this provide the same set of overloads that Append()
626 // does?
627 iterator Insert(const_iterator pos, Value&& value);
628
629 // Erases all values equal to `value` from this list.
630 size_t EraseValue(const Value& value);
631
632 // Erases all values for which `predicate` evaluates to true from this list.
633 template <typename Predicate>
634 size_t EraseIf(Predicate predicate) {
635 return base::EraseIf(storage_, predicate);
636 }
637
Scott Haseleye51040782022-03-09 17:32:37638 // Serializes to a string for logging and debug purposes.
639 std::string DebugString() const;
640
Daniel Chenga367fe52022-02-15 18:08:48641 private:
642 BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs);
643 BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs);
644 BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs);
645 BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs);
646 BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs);
647 BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs);
648
649 // For legacy access to the internal storage type.
650 friend Value;
651
652 explicit List(const std::vector<Value>& storage);
653
654 std::vector<Value> storage_;
655 };
jdoerriee03e80f2017-02-15 08:42:14656
Daniel Cheng619653b2022-02-17 18:33:12657 // ===== DEPRECATED methods that require `type() == Type::LIST` =====
658
Jan Wilken Dörrie69a65a3a2020-01-16 15:03:30659 // Returns the Values in a list as a view. The mutable overload allows for
660 // modification of the underlying values, but does not allow changing the
Daniel Cheng60e6b2d2022-02-05 01:08:46661 // structure of the list. If this is desired, use `TakeListDeprecated()`,
662 // perform the operations, and return the list back to the Value via move
663 // assignment.
Daniel Cheng619653b2022-02-17 18:33:12664 //
665 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
666 // `GetList()` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06667 DeprecatedListView GetListDeprecated();
668 DeprecatedConstListView GetListDeprecated() const;
jdoerrie2b7d0fcd2017-04-19 07:15:38669
Lei Zhang20b21af82020-08-10 18:31:58670 // Transfers ownership of the underlying list to the caller. Subsequent
Daniel Cheng60e6b2d2022-02-05 01:08:46671 // calls to `GetListDeprecated()` will return an empty list.
Daniel Cheng619653b2022-02-17 18:33:12672 //
673 // DEPRECATED: prefer direct use of `base::Value::List` where possible, or
674 // `std::move(value.GetList())` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06675 DeprecatedListStorage TakeListDeprecated() &&;
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05676
Gabriel Charetteb49d73a2021-05-05 20:05:59677 // Appends `value` to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:12678 //
679 // DEPRECATED: prefer `Value::List::Append()`.
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24680 void Append(Value&& value);
Daniel Cheng619653b2022-02-17 18:33:12681 // DEPRECATED: prefer `Value::List::Append()`.
682 void Append(bool value);
683 template <typename T>
684 void Append(const T* ptr) = delete;
685 // DEPRECATED: prefer `Value::List::Append()`.
686 void Append(int value);
687 // DEPRECATED: prefer `Value::List::Append()`.
688 void Append(double value);
689 // DEPRECATED: prefer `Value::List::Append()`.
690 void Append(StringPiece value);
691 // DEPRECATED: prefer `Value::List::Append()`.
692 void Append(StringPiece16 value);
693 // DEPRECATED: prefer `Value::List::Append()`.
694 void Append(const char* value);
695 // DEPRECATED: prefer `Value::List::Append()`.
696 void Append(const char16_t* value);
697 // DEPRECATED: prefer `Value::List::Append()`.
698 void Append(std::string&& value);
Jan Wilken Dörrie55b0b2b2019-09-10 05:40:24699
Gabriel Charetteb49d73a2021-05-05 20:05:59700 // Inserts `value` before `pos`.
Daniel Cheng619653b2022-02-17 18:33:12701 //
702 // DEPRECATED: prefer `Value::List::Insert()`.
Jan Wilken Dörrie9065545e12019-10-30 10:44:51703 CheckedContiguousIterator<Value> Insert(
704 CheckedContiguousConstIterator<Value> pos,
705 Value&& value);
706
Gabriel Charetteb49d73a2021-05-05 20:05:59707 // Erases the Value pointed to by `iter`. Returns false if `iter` is out of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05708 // bounds.
Daniel Cheng619653b2022-02-17 18:33:12709 //
710 // DEPRECATED: prefer `Value::List::erase(iter)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05711 bool EraseListIter(CheckedContiguousConstIterator<Value> iter);
712
Gabriel Charetteb49d73a2021-05-05 20:05:59713 // Erases all Values that compare equal to `val`. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05714 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12715 //
716 // DEPRECATED: prefer `Value::List::EraseValue(val)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05717 size_t EraseListValue(const Value& val);
718
Gabriel Charetteb49d73a2021-05-05 20:05:59719 // Erases all Values for which `pred` returns true. Returns the number of
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05720 // deleted Values.
Daniel Cheng619653b2022-02-17 18:33:12721 //
722 // DEPRECATED: prefer `Value::List::EraseIf(pred)`.
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05723 template <typename Predicate>
724 size_t EraseListValueIf(Predicate pred) {
Jan Wilken Dörrie79d022142020-08-19 18:18:32725 return base::EraseIf(list(), pred);
Jan Wilken Dörrie7e7a9792019-10-15 14:42:05726 }
727
Jan Wilken Dörrie02577a22019-12-04 14:27:39728 // Erases all Values from the list.
Daniel Cheng619653b2022-02-17 18:33:12729 //
730 // DEPRECATED: prefer `Value::List::clear()`.
Jan Wilken Dörrie02577a22019-12-04 14:27:39731 void ClearList();
732
Daniel Cheng619653b2022-02-17 18:33:12733 // ===== DEPRECATED methods that require `type() == Type::DICT` =====
734
Gabriel Charetteb49d73a2021-05-05 20:05:59735 // `FindKey` looks up `key` in the underlying dictionary. If found, it returns
jdoerrie78ab7a22017-08-17 19:04:45736 // a pointer to the element. Otherwise it returns nullptr.
jdoerrie78ab7a22017-08-17 19:04:45737 //
Daniel Cheng619653b2022-02-17 18:33:12738 // DEPRECATED: prefer `Value::Dict::Find()`.
jdoerrie78ab7a22017-08-17 19:04:45739 Value* FindKey(StringPiece key);
740 const Value* FindKey(StringPiece key) const;
jdoerrie44efa9d2017-07-14 14:47:20741
Gabriel Charetteb49d73a2021-05-05 20:05:59742 // `FindKeyOfType` is similar to `FindKey`, but it also requires the found
743 // value to have type `type`. If no type is found, or the found value is of a
jdoerrie78ab7a22017-08-17 19:04:45744 // different type nullptr is returned.
jdoerrie78ab7a22017-08-17 19:04:45745 //
Daniel Cheng619653b2022-02-17 18:33:12746 // DEPRECATED: prefer `Value::Dict::FindBool()`, `Value::Dict::FindInt()`, et
747 // cetera.
jdoerrie78ab7a22017-08-17 19:04:45748 Value* FindKeyOfType(StringPiece key, Type type);
749 const Value* FindKeyOfType(StringPiece key, Type type) const;
jdoerrie44efa9d2017-07-14 14:47:20750
Daniel Cheng619653b2022-02-17 18:33:12751 // These are convenience forms of `FindKey`. They return `absl::nullopt` or
752 // `nullptr` if the value is not found or doesn't have the type specified in
753 // the function's name.
754 //
755 // DEPRECATED: prefer `Value::Dict::FindBool()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39756 absl::optional<bool> FindBoolKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12757 // DEPRECATED: prefer `Value::Dict::FindInt()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39758 absl::optional<int> FindIntKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12759 // Returns a non-null value for both `Value::Type::DOUBLE` and
760 // `Value::Type::INT`, converting the latter to a double.
761 //
762 // DEPRECATED: prefer `Value::Dict::FindDouble()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39763 absl::optional<double> FindDoubleKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12764 // DEPRECATED: prefer `Value::Dict::FindString()`.
Vladislav Kuzkokov193a2ba2019-01-08 11:33:16765 const std::string* FindStringKey(StringPiece key) const;
Dominic Battre08cbe972019-07-31 03:57:19766 std::string* FindStringKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12767 // DEPRECATED: prefer `Value::Dict::FindBlob()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06768 const BlobStorage* FindBlobKey(StringPiece key) const;
Daniel Cheng619653b2022-02-17 18:33:12769 // DEPRECATED: prefer `Value::Dict::FindDict()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06770 const Value* FindDictKey(StringPiece key) const;
771 Value* FindDictKey(StringPiece key);
Daniel Cheng619653b2022-02-17 18:33:12772 // DEPRECATED: prefer `Value::Dict::FindList()`.
David 'Digit' Turnerfca8c4b52019-03-26 11:14:06773 const Value* FindListKey(StringPiece key) const;
774 Value* FindListKey(StringPiece key);
775
Gabriel Charetteb49d73a2021-05-05 20:05:59776 // `SetKey` looks up `key` in the underlying dictionary and sets the mapped
777 // value to `value`. If `key` could not be found, a new element is inserted.
jdoerrie78ab7a22017-08-17 19:04:45778 // A pointer to the modified item is returned.
jdoerrie78ab7a22017-08-17 19:04:45779 //
Daniel Cheng619653b2022-02-17 18:33:12780 // Note: Prefer `Set<Type>Key()` if the input is not already a `Value`.
781 //
782 // DEPRECATED: Prefer `Value::Dict::Set()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16783 Value* SetKey(StringPiece key, Value&& value);
jdoerrie44efa9d2017-07-14 14:47:20784
Gabriel Charetteb49d73a2021-05-05 20:05:59785 // `Set`Type>Key` looks up `key` in the underlying dictionary and associates a
786 // corresponding Value() constructed from the second parameter. Compared to
787 // `SetKey()`, this avoids un-necessary temporary `Value()` creation, as well
David 'Digit' Turnere169e6c2019-03-28 22:06:29788 // ambiguities in the value type.
Daniel Cheng619653b2022-02-17 18:33:12789 //
790 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29791 Value* SetBoolKey(StringPiece key, bool val);
Daniel Cheng619653b2022-02-17 18:33:12792 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29793 Value* SetIntKey(StringPiece key, int val);
Daniel Cheng619653b2022-02-17 18:33:12794 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29795 Value* SetDoubleKey(StringPiece key, double val);
Daniel Cheng619653b2022-02-17 18:33:12796 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29797 Value* SetStringKey(StringPiece key, StringPiece val);
Daniel Cheng619653b2022-02-17 18:33:12798 // DEPRECATED: Prefer `Value::Dict::Set()`.
Jan Wilken Dörrie293405a2020-05-12 19:45:11799 Value* SetStringKey(StringPiece key, StringPiece16 val);
Daniel Cheng619653b2022-02-17 18:33:12800 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29801 Value* SetStringKey(StringPiece key, const char* val);
Daniel Cheng619653b2022-02-17 18:33:12802 // DEPRECATED: Prefer `Value::Dict::Set()`.
David 'Digit' Turnere169e6c2019-03-28 22:06:29803 Value* SetStringKey(StringPiece key, std::string&& val);
David 'Digit' Turnere169e6c2019-03-28 22:06:29804
Gabriel Charetteb49d73a2021-05-05 20:05:59805 // This attempts to remove the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46806 // failure, e.g. the key does not exist, false is returned and the underlying
Gabriel Charetteb49d73a2021-05-05 20:05:59807 // dictionary is not changed. In case of success, `key` is deleted from the
jdoerriec209c7d2019-04-05 09:51:46808 // dictionary and the method returns true.
jdoerrie64783162017-09-04 16:33:32809 //
Daniel Cheng619653b2022-02-17 18:33:12810 // Deprecated: Prefer `Value::Dict::Remove()`.
jdoerrie64783162017-09-04 16:33:32811 bool RemoveKey(StringPiece key);
812
Gabriel Charetteb49d73a2021-05-05 20:05:59813 // This attempts to extract the value associated with `key`. In case of
jdoerriec209c7d2019-04-05 09:51:46814 // failure, e.g. the key does not exist, nullopt is returned and the
Gabriel Charetteb49d73a2021-05-05 20:05:59815 // underlying dictionary is not changed. In case of success, `key` is deleted
jdoerriec209c7d2019-04-05 09:51:46816 // from the dictionary and the method returns the extracted Value.
jdoerriec209c7d2019-04-05 09:51:46817 //
Daniel Cheng619653b2022-02-17 18:33:12818 // DEPRECATED: Prefer `Value::Dict::Extract()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39819 absl::optional<Value> ExtractKey(StringPiece key);
jdoerriec209c7d2019-04-05 09:51:46820
Brett Wilsond16cf4ee2017-08-03 00:08:27821 // Searches a hierarchy of dictionary values for a given value. If a path
822 // of dictionaries exist, returns the item at that path. If any of the path
823 // components do not exist or if any but the last path components are not
Daniel Cheng619653b2022-02-17 18:33:12824 // dictionaries, returns nullptr. The type of the leaf Value is not checked.
Brett Wilsond16cf4ee2017-08-03 00:08:27825 //
David 'Digit' Turner43ce6492019-04-04 16:04:44826 // This version takes a StringPiece for the path, using dots as separators.
Daniel Cheng619653b2022-02-17 18:33:12827 //
828 // DEPRECATED: Prefer `Value::Dict::FindByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44829 Value* FindPath(StringPiece path);
830 const Value* FindPath(StringPiece path) const;
831
832 // There are also deprecated versions that take the path parameter
833 // as either a std::initializer_list<StringPiece> or a
834 // span<const StringPiece>. The latter is useful to use a
835 // std::vector<std::string> as a parameter but creates huge dynamic
jdoerriec209c7d2019-04-05 09:51:46836 // allocations and should be avoided!
Gabriel Charetteb49d73a2021-05-05 20:05:59837 // Note: If there is only one component in the path, use `FindKey()` instead.
jdoerriec209c7d2019-04-05 09:51:46838 //
David 'Digit' Turner43ce6492019-04-04 16:04:44839 // Example:
jdoerriecd022242017-08-23 08:38:27840 // std::vector<StringPiece> components = ...
841 // auto* found = FindPath(components);
Daniel Cheng619653b2022-02-17 18:33:12842 //
843 // DEPRECATED: These are not common, and there is no currently planned
844 // replacement.
jdoerriecd022242017-08-23 08:38:27845 Value* FindPath(std::initializer_list<StringPiece> path);
846 Value* FindPath(span<const StringPiece> path);
847 const Value* FindPath(std::initializer_list<StringPiece> path) const;
848 const Value* FindPath(span<const StringPiece> path) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27849
Lei Zhange0fc6f02017-10-27 00:27:23850 // Like FindPath() but will only return the value if the leaf Value type
Brett Wilsond16cf4ee2017-08-03 00:08:27851 // matches the given type. Will return nullptr otherwise.
Gabriel Charetteb49d73a2021-05-05 20:05:59852 // Note: Prefer `Find<Type>Path()` for simple values.
Lei Zhange0fc6f02017-10-27 00:27:23853 //
Gabriel Charetteb49d73a2021-05-05 20:05:59854 // Note: If there is only one component in the path, use `FindKeyOfType()`
David 'Digit' Turner43ce6492019-04-04 16:04:44855 // instead for slightly better performance.
Daniel Cheng619653b2022-02-17 18:33:12856 //
857 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`,
858 // `Value::Dict::FindIntByDottedPath()`, et cetera.
David 'Digit' Turner43ce6492019-04-04 16:04:44859 Value* FindPathOfType(StringPiece path, Type type);
860 const Value* FindPathOfType(StringPiece path, Type type) const;
861
862 // Convenience accessors used when the expected type of a value is known.
863 // Similar to Find<Type>Key() but accepts paths instead of keys.
Daniel Cheng619653b2022-02-17 18:33:12864 //
865 // DEPRECATED: Use `Value::Dict::FindBoolByDottedPath()`, or
866 // `Value::Dict::FindBool()` if the path only has one component, i.e. has no
867 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39868 absl::optional<bool> FindBoolPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12869 // DEPRECATED: Use `Value::Dict::FindIntByDottedPath()`, or
870 // `Value::Dict::FindInt()` if the path only has one component, i.e. has no
871 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39872 absl::optional<int> FindIntPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12873 // DEPRECATED: Use `Value::Dict::FindDoubleByDottedPath()`, or
874 // `Value::Dict::FindDouble()` if the path only has one component, i.e. has no
875 // dots.
Anton Bikineev7dd58ad2021-05-18 01:01:39876 absl::optional<double> FindDoublePath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12877 // DEPRECATED: Use `Value::Dict::FindStringByDottedPath()`, or
878 // `Value::Dict::FindString()` if the path only has one component, i.e. has no
879 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44880 const std::string* FindStringPath(StringPiece path) const;
Dominic Battre08cbe972019-07-31 03:57:19881 std::string* FindStringPath(StringPiece path);
Daniel Cheng619653b2022-02-17 18:33:12882 // DEPRECATED: Use `Value::Dict::FindBlobByDottedPath()`, or
883 // `Value::Dict::FindBlob()` if the path only has one component, i.e. has no
884 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44885 const BlobStorage* FindBlobPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12886 // DEPRECATED: Use `Value::Dict::FindDictByDottedPath()`, or
887 // `Value::Dict::FindDict()` if the path only has one component, i.e. has no
888 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44889 Value* FindDictPath(StringPiece path);
890 const Value* FindDictPath(StringPiece path) const;
Daniel Cheng619653b2022-02-17 18:33:12891 // DEPRECATED: Use `Value::Dict::FindListByDottedPath()`, or
892 // `Value::Dict::FindList()` if the path only has one component, i.e. has no
893 // dots.
David 'Digit' Turner43ce6492019-04-04 16:04:44894 Value* FindListPath(StringPiece path);
895 const Value* FindListPath(StringPiece path) const;
896
897 // The following forms are deprecated too, use the ones that take the path
898 // as a single StringPiece instead.
Daniel Cheng619653b2022-02-17 18:33:12899 //
900 // DEPRECATED: These are not common, and there is no currently planned
901 // replacement.
jdoerriecd022242017-08-23 08:38:27902 Value* FindPathOfType(std::initializer_list<StringPiece> path, Type type);
903 Value* FindPathOfType(span<const StringPiece> path, Type type);
904 const Value* FindPathOfType(std::initializer_list<StringPiece> path,
Brett Wilsond16cf4ee2017-08-03 00:08:27905 Type type) const;
jdoerriecd022242017-08-23 08:38:27906 const Value* FindPathOfType(span<const StringPiece> path, Type type) const;
Brett Wilsond16cf4ee2017-08-03 00:08:27907
908 // Sets the given path, expanding and creating dictionary keys as necessary.
909 //
jdoerrie64783162017-09-04 16:33:32910 // If the current value is not a dictionary, the function returns nullptr. If
911 // path components do not exist, they will be created. If any but the last
912 // components matches a value that is not a dictionary, the function will fail
913 // (it will not overwrite the value) and return nullptr. The last path
914 // component will be unconditionally overwritten if it exists, and created if
915 // it doesn't.
Brett Wilsond16cf4ee2017-08-03 00:08:27916 //
Gabriel Charetteb49d73a2021-05-05 20:05:59917 // Note: If there is only one component in the path, use `SetKey()` instead.
918 // Note: Using `Set<Type>Path()` might be more convenient and efficient.
Daniel Cheng619653b2022-02-17 18:33:12919 //
920 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44921 Value* SetPath(StringPiece path, Value&& value);
922
923 // These setters are more convenient and efficient than the corresponding
924 // SetPath(...) call.
Daniel Cheng619653b2022-02-17 18:33:12925 //
926 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44927 Value* SetBoolPath(StringPiece path, bool value);
Daniel Cheng619653b2022-02-17 18:33:12928 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44929 Value* SetIntPath(StringPiece path, int value);
Daniel Cheng619653b2022-02-17 18:33:12930 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44931 Value* SetDoublePath(StringPiece path, double value);
Daniel Cheng619653b2022-02-17 18:33:12932 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44933 Value* SetStringPath(StringPiece path, StringPiece value);
Daniel Cheng619653b2022-02-17 18:33:12934 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44935 Value* SetStringPath(StringPiece path, const char* value);
Daniel Cheng619653b2022-02-17 18:33:12936 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44937 Value* SetStringPath(StringPiece path, std::string&& value);
Daniel Cheng619653b2022-02-17 18:33:12938 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44939 Value* SetStringPath(StringPiece path, StringPiece16 value);
940
Daniel Cheng619653b2022-02-17 18:33:12941 // DEPRECATED: Use `Value::Dict::SetByDottedPath()`.
Sergey Abbakumov0e1215882019-03-15 22:32:16942 Value* SetPath(std::initializer_list<StringPiece> path, Value&& value);
943 Value* SetPath(span<const StringPiece> path, Value&& value);
Brett Wilsond16cf4ee2017-08-03 00:08:27944
jdoerrie64783162017-09-04 16:33:32945 // Tries to remove a Value at the given path.
946 //
jdoerriec209c7d2019-04-05 09:51:46947 // If the current value is not a dictionary or any path component does not
jdoerrie64783162017-09-04 16:33:32948 // exist, this operation fails, leaves underlying Values untouched and returns
Gabriel Charetteb49d73a2021-05-05 20:05:59949 // `false`. In case intermediate dictionaries become empty as a result of this
jdoerrie64783162017-09-04 16:33:32950 // path removal, they will be removed as well.
Song Fangzhen09e06912021-07-21 15:01:28951 // Note: If there is only one component in the path, use `RemoveKey()`
Gabriel Charetteb49d73a2021-05-05 20:05:59952 // instead.
jdoerrie64783162017-09-04 16:33:32953 //
Daniel Cheng619653b2022-02-17 18:33:12954 // DEPRECATED: Use `Value::Dict::RemoveByDottedPath()`.
David 'Digit' Turner43ce6492019-04-04 16:04:44955 bool RemovePath(StringPiece path);
956
jdoerriec209c7d2019-04-05 09:51:46957 // Tries to extract a Value at the given path.
958 //
959 // If the current value is not a dictionary or any path component does not
960 // exist, this operation fails, leaves underlying Values untouched and returns
961 // nullopt. In case intermediate dictionaries become empty as a result of this
962 // path removal, they will be removed as well. Returns the extracted value on
963 // success.
Gabriel Charetteb49d73a2021-05-05 20:05:59964 // Note: If there is only one component in the path, use `ExtractKey()`
965 // instead.
jdoerriec209c7d2019-04-05 09:51:46966 //
Daniel Cheng619653b2022-02-17 18:33:12967 // DEPRECATED: Use `Value::Dict::ExtractByDottedPath()`.
Anton Bikineev7dd58ad2021-05-18 01:01:39968 absl::optional<Value> ExtractPath(StringPiece path);
jdoerriec209c7d2019-04-05 09:51:46969
jdoerrie78ab7a22017-08-17 19:04:45970 using dict_iterator_proxy = detail::dict_iterator_proxy;
971 using const_dict_iterator_proxy = detail::const_dict_iterator_proxy;
jdoerrie44efa9d2017-07-14 14:47:20972
Gabriel Charetteb49d73a2021-05-05 20:05:59973 // `DictItems` returns a proxy object that exposes iterators to the underlying
jdoerrie44efa9d2017-07-14 14:47:20974 // dictionary. These are intended for iteration over all items in the
975 // dictionary and are compatible with for-each loops and standard library
976 // algorithms.
David Van Cleve373381d2020-01-07 18:16:13977 //
Gabriel Charetteb49d73a2021-05-05 20:05:59978 // Unlike with std::map, a range-for over the non-const version of
979 // `DictItems()` will range over items of type
980 // `pair<const std::string&, Value&>`, so code of the form
David Van Cleve373381d2020-01-07 18:16:13981 // for (auto kv : my_value.DictItems())
982 // Mutate(kv.second);
Gabriel Charetteb49d73a2021-05-05 20:05:59983 // will actually alter `my_value` in place (if it isn't const).
David Van Cleve373381d2020-01-07 18:16:13984 //
Daniel Cheng619653b2022-02-17 18:33:12985 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
986 // instead.
jdoerrie44efa9d2017-07-14 14:47:20987 dict_iterator_proxy DictItems();
988 const_dict_iterator_proxy DictItems() const;
989
Jan Wilken Dörrief961a372020-11-02 20:30:34990 // Transfers ownership of the underlying dict to the caller. Subsequent
991 // calls to DictItems() will return an empty dict.
Daniel Cheng619653b2022-02-17 18:33:12992 //
993 // DEPRECATED: prefer direct use of `base::Value::Dict` where possible, or
994 // `std::move(value.GetDict())` otherwise.
Daniel Cheng773ce4502022-01-28 15:25:06995 DeprecatedDictStorage TakeDictDeprecated() &&;
Jan Wilken Dörrief961a372020-11-02 20:30:34996
Daniel Cheng619653b2022-02-17 18:33:12997 // DEPRECATED: prefer `Value::Dict::size()`.
Lei Zhange823c512018-05-07 20:27:30998 size_t DictSize() const;
Daniel Cheng619653b2022-02-17 18:33:12999
1000 // DEPRECATED: prefer `Value::Dict::empty()`.
Lei Zhange823c512018-05-07 20:27:301001 bool DictEmpty() const;
Daniel Cheng619653b2022-02-17 18:33:121002
1003 // DEPRECATED: prefer `Value::Dict::clear()`.
Panos Astithas0532a862020-10-29 04:15:071004 void DictClear();
Lei Zhange823c512018-05-07 20:27:301005
Gabriel Charetteb49d73a2021-05-05 20:05:591006 // Merge `dictionary` into this value. This is done recursively, i.e. any
jdoerriec1091282018-08-01 17:28:121007 // sub-dictionaries will be merged as well. In case of key collisions, the
1008 // passed in dictionary takes precedence and data already present will be
Gabriel Charetteb49d73a2021-05-05 20:05:591009 // replaced. Values within `dictionary` are deep-copied, so `dictionary` may
jdoerriec1091282018-08-01 17:28:121010 // be freed any time after this call.
Gabriel Charetteb49d73a2021-05-05 20:05:591011 // Note: This requires that `type()` and `dictionary->type()` is
Daniel Chenga367fe52022-02-15 18:08:481012 // Type::DICT.
Daniel Cheng619653b2022-02-17 18:33:121013 //
1014 // DEPRECATED: prefer `Value::Dict::Merge()`.
jdoerriec1091282018-08-01 17:28:121015 void MergeDictionary(const Value* dictionary);
1016
[email protected]2f03f532013-07-17 08:43:331017 // These methods allow the convenient retrieval of the contents of the Value.
1018 // If the current object can be converted into the given type, the value is
Gabriel Charetteb49d73a2021-05-05 20:05:591019 // returned through the `out_value` parameter and true is returned;
1020 // otherwise, false is returned and `out_value` is unchanged.
lukaszad1485da72016-11-01 21:49:461021 // ListValue::From is the equivalent for std::unique_ptr conversions.
Daniel Cheng619653b2022-02-17 18:33:121022 //
1023 // DEPRECATED: prefer direct use `base::Value::List` where possible, or
1024 // `GetIfList()` otherwise.
jdoerrie8e945542017-02-17 13:54:491025 bool GetAsList(ListValue** out_value);
1026 bool GetAsList(const ListValue** out_value) const;
lukaszad1485da72016-11-01 21:49:461027 // DictionaryValue::From is the equivalent for std::unique_ptr conversions.
Daniel Cheng619653b2022-02-17 18:33:121028 //
1029 // DEPRECATED: prefer direct use `base::Value::Dict` where possible, or
1030 // `GetIfDict()` otherwise.
jdoerrie8e945542017-02-17 13:54:491031 bool GetAsDictionary(DictionaryValue** out_value);
1032 bool GetAsDictionary(const DictionaryValue** out_value) const;
[email protected]2f03f532013-07-17 08:43:331033 // Note: Do not add more types. See the file-level comment above for why.
initial.commitd7cae122008-07-26 21:49:381034
1035 // This creates a deep copy of the entire Value tree, and returns a pointer
jdoerrie05eb3162017-02-01 10:36:561036 // to the copy. The caller gets ownership of the copy, of course.
[email protected]16f47e082011-01-18 02:16:591037 // Subclasses return their own type directly in their overrides;
1038 // this works because C++ supports covariant return types.
jdoerriee964d9a2017-04-05 06:44:171039 // TODO(crbug.com/646113): Delete this and migrate callsites.
Daniel Cheng619653b2022-02-17 18:33:121040 //
1041 // DEPRECATED: prefer `Value::Clone()`.
dcheng093de9b2016-04-04 21:25:511042 std::unique_ptr<Value> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381043
jdoerrie5c1cee112017-03-28 17:52:001044 // Comparison operators so that Values can easily be used with standard
1045 // library algorithms and associative containers.
1046 BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs);
1047 BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs);
1048 BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs);
1049 BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs);
1050 BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs);
1051 BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs);
1052
initial.commitd7cae122008-07-26 21:49:381053 // Compares if two Value objects have equal contents.
Gabriel Charetteb49d73a2021-05-05 20:05:591054 // DEPRECATED, use `operator==(const Value& lhs, const Value& rhs)` instead.
jdoerrie5c1cee112017-03-28 17:52:001055 // TODO(crbug.com/646113): Delete this and migrate callsites.
Daniel Cheng619653b2022-02-17 18:33:121056 //
1057 // DEPRECATED: prefer direct use of the equality operator instead.
jdoerrie8e945542017-02-17 13:54:491058 bool Equals(const Value* other) const;
initial.commitd7cae122008-07-26 21:49:381059
Eric Secklerf6c544f2020-06-02 10:49:211060 // Estimates dynamic memory usage. Requires tracing support
1061 // (enable_base_tracing gn flag), otherwise always returns 0. See
1062 // base/trace_event/memory_usage_estimator.h for more info.
Alexander Yashkinab504e72017-11-30 11:54:451063 size_t EstimateMemoryUsage() const;
1064
Alan Cutter2dd83032020-12-08 21:55:001065 // Serializes to a string for logging and debug purposes.
1066 std::string DebugString() const;
1067
Peter Kotwicz83a231372021-04-13 17:42:121068#if BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211069 // Write this object into a trace.
Alexander Timinbebb2002021-04-20 15:42:241070 void WriteIntoTrace(perfetto::TracedValue) const;
Peter Kotwicz83a231372021-04-13 17:42:121071#endif // BUILDFLAG(ENABLE_BASE_TRACING)
Alexander Timine68aeb32021-04-11 23:06:211072
Daniel Cheng8ac305b2022-02-17 00:05:111073 template <typename Visitor>
1074 auto Visit(Visitor&& visitor) const {
1075 return absl::visit(std::forward<Visitor>(visitor), data_);
1076 }
1077
jdoerrie8e945542017-02-17 13:54:491078 protected:
Jan Wilken Dörrie79d022142020-08-19 18:18:321079 // Checked convenience accessors for dict and list.
Daniel Chenga367fe52022-02-15 18:08:481080 const LegacyDictStorage& dict() const { return GetDict().storage_; }
1081 LegacyDictStorage& dict() { return GetDict().storage_; }
1082 const ListStorage& list() const { return GetList().storage_; }
1083 ListStorage& list() { return GetList().storage_; }
Jan Wilken Dörrie79d022142020-08-19 18:18:321084
Jan Wilken Dörrief961a372020-11-02 20:30:341085 // Internal constructors, allowing the simplify the implementation of Clone().
1086 explicit Value(const LegacyDictStorage& storage);
1087 explicit Value(LegacyDictStorage&& storage) noexcept;
1088
Jan Wilken Dörrie79d022142020-08-19 18:18:321089 private:
Daniel Cheng8ac305b2022-02-17 00:05:111090 // For access to DoubleStorage.
1091 friend class ValueView;
1092
David 'Digit' Turner2f287312019-04-03 14:32:091093 // Special case for doubles, which are aligned to 8 bytes on some
1094 // 32-bit architectures. In this case, a simple declaration as a
1095 // double member would make the whole union 8 byte-aligned, which
1096 // would also force 4 bytes of wasted padding space before it in
1097 // the Value layout.
David 'Digit' Turner806dedb82019-03-06 17:43:111098 //
David 'Digit' Turner2f287312019-04-03 14:32:091099 // To override this, store the value as an array of 32-bit integers, and
1100 // perform the appropriate bit casts when reading / writing to it.
Daniel Cheng782d2ba32022-02-16 19:40:291101 class DoubleStorage {
1102 public:
1103 explicit DoubleStorage(double v);
1104 DoubleStorage(const DoubleStorage&) = default;
1105 DoubleStorage& operator=(const DoubleStorage&) = default;
1106
Daniel Cheng8ac305b2022-02-17 00:05:111107 // Provide an implicit conversion to double to simplify the use of visitors
1108 // with `Value::Visit()`. Otherwise, visitors would need a branch for
1109 // handling `DoubleStorage` like:
1110 //
1111 // value.Visit([] (const auto& member) {
1112 // using T = std::decay_t<decltype(member)>;
1113 // if constexpr (std::is_same_v<T, Value::DoubleStorage>) {
1114 // SomeFunction(double{member});
1115 // } else {
1116 // SomeFunction(member);
1117 // }
1118 // });
Peter Kastingcc88ac052022-05-03 09:58:011119 operator double() const { return base::bit_cast<double>(v_); }
Daniel Cheng782d2ba32022-02-16 19:40:291120
1121 private:
1122 friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111123 return double{lhs} == double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291124 }
1125
1126 friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1127 return !(lhs == rhs);
1128 }
1129
1130 friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) {
Daniel Cheng8ac305b2022-02-17 00:05:111131 return double{lhs} < double{rhs};
Daniel Cheng782d2ba32022-02-16 19:40:291132 }
1133
1134 friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1135 return rhs < lhs;
1136 }
1137
1138 friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1139 return !(rhs < lhs);
1140 }
1141
1142 friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) {
1143 return !(lhs < rhs);
1144 }
1145
1146 alignas(4) std::array<char, sizeof(double)> v_;
1147 };
David 'Digit' Turner2f287312019-04-03 14:32:091148
Jan Wilken Dörrie79d022142020-08-19 18:18:321149 // Internal constructors, allowing the simplify the implementation of Clone().
1150 explicit Value(absl::monostate);
1151 explicit Value(DoubleStorage storage);
jdoerrie8e945542017-02-17 13:54:491152
Jan Wilken Dörrie79d022142020-08-19 18:18:321153 absl::variant<absl::monostate,
1154 bool,
1155 int,
1156 DoubleStorage,
1157 std::string,
1158 BlobStorage,
Daniel Chenga367fe52022-02-15 18:08:481159 Dict,
1160 List>
Jan Wilken Dörrie79d022142020-08-19 18:18:321161 data_;
initial.commitd7cae122008-07-26 21:49:381162};
1163
[email protected]9e4cda7332010-07-31 04:56:141164// DictionaryValue provides a key-value dictionary with (optional) "path"
1165// parsing for recursive access; see the comment at the top of the file. Keys
Gabriel Charetted7c00cbe2021-05-14 20:05:531166// are std::string's and should be UTF-8 encoded.
Daniel Cheng619653b2022-02-17 18:33:121167//
1168// DEPRECATED: prefer `Value::Dict`.
[email protected]0bea7252011-08-05 15:34:001169class BASE_EXPORT DictionaryValue : public Value {
initial.commitd7cae122008-07-26 21:49:381170 public:
Gabriel Charetteb49d73a2021-05-05 20:05:591171 // Returns `value` if it is a dictionary, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511172 static std::unique_ptr<DictionaryValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541173
[email protected]3a3d47472010-07-15 21:03:541174 DictionaryValue();
Jan Wilken Dörrief961a372020-11-02 20:30:341175 explicit DictionaryValue(const LegacyDictStorage& in_dict);
1176 explicit DictionaryValue(LegacyDictStorage&& in_dict) noexcept;
[email protected]5cf906f82011-11-26 01:11:441177
initial.commitd7cae122008-07-26 21:49:381178 // Returns true if the current dictionary has a value for the given key.
Daniel Cheng619653b2022-02-17 18:33:121179 //
1180 // DEPRECATED: prefer `Value::Dict::contains()`.
dcheng16d6f532016-08-25 16:07:111181 bool HasKey(StringPiece key) const;
initial.commitd7cae122008-07-26 21:49:381182
initial.commitd7cae122008-07-26 21:49:381183 // Sets the Value associated with the given path starting from this object.
1184 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1185 // into the next DictionaryValue down. Obviously, "." can't be used
1186 // within a key, but there are no other restrictions on keys.
1187 // If the key at any step of the way doesn't exist, or exists but isn't
1188 // a DictionaryValue, a new DictionaryValue will be created and attached
Gabriel Charetteb49d73a2021-05-05 20:05:591189 // to the path in that location. `in_value` must be non-null.
jdoerrieb94e5422017-04-28 21:52:581190 // Returns a pointer to the inserted value.
Daniel Cheng619653b2022-02-17 18:33:121191 //
1192 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1193 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1194 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581195 Value* Set(StringPiece path, std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381196
1197 // Convenience forms of Set(). These methods will replace any existing
1198 // value at that path, even if it has a different type.
Daniel Cheng619653b2022-02-17 18:33:121199 //
1200 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1201 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1202 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581203 Value* SetBoolean(StringPiece path, bool in_value);
Daniel Cheng619653b2022-02-17 18:33:121204 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1205 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1206 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581207 Value* SetInteger(StringPiece path, int in_value);
Daniel Cheng619653b2022-02-17 18:33:121208 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1209 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1210 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581211 Value* SetDouble(StringPiece path, double in_value);
Daniel Cheng619653b2022-02-17 18:33:121212 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1213 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1214 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581215 Value* SetString(StringPiece path, StringPiece in_value);
Daniel Cheng619653b2022-02-17 18:33:121216 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1217 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1218 // otherwise.
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571219 Value* SetString(StringPiece path, const std::u16string& in_value);
Daniel Cheng619653b2022-02-17 18:33:121220 // DEPRECATED: prefer `Value::Dict::Set()` (if the path only has one
1221 // component, i.e. has no dots), or `Value::Dict::SetByDottedPath()`
1222 // otherwise.
jdoerrieb94e5422017-04-28 21:52:581223 ListValue* SetList(StringPiece path, std::unique_ptr<ListValue> in_value);
[email protected]4dad9ad82009-11-25 20:47:521224
1225 // Like Set(), but without special treatment of '.'. This allows e.g. URLs to
1226 // be used as paths.
Daniel Cheng619653b2022-02-17 18:33:121227 //
1228 // DEPRECATED: prefer `Value::Dict::Set()`.
jdoerrieb94e5422017-04-28 21:52:581229 Value* SetWithoutPathExpansion(StringPiece key,
1230 std::unique_ptr<Value> in_value);
initial.commitd7cae122008-07-26 21:49:381231
1232 // Gets the Value associated with the given path starting from this object.
1233 // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes
1234 // into the next DictionaryValue down. If the path can be resolved
1235 // successfully, the value for the last key in the path will be returned
Gabriel Charetteb49d73a2021-05-05 20:05:591236 // through the `out_value` parameter, and the function will return true.
1237 // Otherwise, it will return false and `out_value` will be untouched.
initial.commitd7cae122008-07-26 21:49:381238 // Note that the dictionary always owns the value that's returned.
Gabriel Charetteb49d73a2021-05-05 20:05:591239 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121240 //
1241 // DEPRECATED: prefer `Value::Dict::Find()` (if the path only has one
1242 // component, i.e. has no dots), or `Value::Dict::FindByDottedPath()`
1243 // otherwise.
asvitkinedbd26533e2015-06-23 18:22:521244 bool Get(StringPiece path, const Value** out_value) const;
1245 bool Get(StringPiece path, Value** out_value);
initial.commitd7cae122008-07-26 21:49:381246
Gabriel Charetteb49d73a2021-05-05 20:05:591247 // These are convenience forms of `Get()`. The value will be retrieved
initial.commitd7cae122008-07-26 21:49:381248 // and the return value will be true if the path is valid and the value at
1249 // the end of the path can be returned in the form specified.
Gabriel Charetteb49d73a2021-05-05 20:05:591250 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121251 //
1252 // DEPRECATED: prefer `Value::Dict::FindInt()` (if the path only has one
1253 // component, i.e. has no dots), or `Value::Dict::FindIntByDottedPath()`
1254 // otherwise.
dcheng16d6f532016-08-25 16:07:111255 bool GetInteger(StringPiece path, int* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121256 // DEPRECATED: prefer `Value::Dict::FindString()` (if the path only has one
1257 // component, i.e. has no dots), or `Value::Dict::FindStringByDottedPath()`
1258 // otherwise.
dcheng16d6f532016-08-25 16:07:111259 bool GetString(StringPiece path, std::string* out_value) const;
Jan Wilken Dörrie085b2aa2021-03-12 16:26:571260 bool GetString(StringPiece path, std::u16string* out_value) const;
Daniel Cheng619653b2022-02-17 18:33:121261 // DEPRECATED: prefer `Value::Dict::FindDict()` (if the path only has one
1262 // component, i.e. has no dots), or `Value::Dict::FindDictByDottedPath()`
1263 // otherwise.
Jan Wilken Dörrie79d022142020-08-19 18:18:321264 bool GetDictionary(StringPiece path, const DictionaryValue** out_value) const;
asvitkinedbd26533e2015-06-23 18:22:521265 bool GetDictionary(StringPiece path, DictionaryValue** out_value);
Daniel Cheng619653b2022-02-17 18:33:121266 // DEPRECATED: prefer `Value::Dict::FindList()` (if the path only has one
1267 // component, i.e. has no dots), or `Value::Dict::FindListByDottedPath()`
1268 // otherwise.
dcheng16d6f532016-08-25 16:07:111269 bool GetList(StringPiece path, const ListValue** out_value) const;
1270 bool GetList(StringPiece path, ListValue** out_value);
initial.commitd7cae122008-07-26 21:49:381271
Gabriel Charetteb49d73a2021-05-05 20:05:591272 // Like `Get()`, but without special treatment of '.'. This allows e.g. URLs
1273 // to be used as paths.
Gabriel Charetteb49d73a2021-05-05 20:05:591274 // DEPRECATED, use `Value::FindDictKey(key)` instead.
[email protected]a61890e2012-07-27 22:27:111275 bool GetDictionaryWithoutPathExpansion(
dcheng16d6f532016-08-25 16:07:111276 StringPiece key,
[email protected]a61890e2012-07-27 22:27:111277 const DictionaryValue** out_value) const;
Gabriel Charetteb49d73a2021-05-05 20:05:591278 // DEPRECATED, use `Value::FindDictKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111279 bool GetDictionaryWithoutPathExpansion(StringPiece key,
[email protected]a61890e2012-07-27 22:27:111280 DictionaryValue** out_value);
Gabriel Charetteb49d73a2021-05-05 20:05:591281 // DEPRECATED, use `Value::FindListKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111282 bool GetListWithoutPathExpansion(StringPiece key,
[email protected]a61890e2012-07-27 22:27:111283 const ListValue** out_value) const;
Gabriel Charetteb49d73a2021-05-05 20:05:591284 // DEPRECATED, use `Value::FindListKey(key)` instead.
dcheng16d6f532016-08-25 16:07:111285 bool GetListWithoutPathExpansion(StringPiece key, ListValue** out_value);
[email protected]4dad9ad82009-11-25 20:47:521286
Gabriel Charetteb49d73a2021-05-05 20:05:591287 // Makes a copy of `this` but doesn't include empty dictionaries and lists in
1288 // the copy. This never returns NULL, even if `this` itself is empty.
dcheng093de9b2016-04-04 21:25:511289 std::unique_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const;
[email protected]ec330b52009-12-02 00:20:321290
Gabriel Charetteb49d73a2021-05-05 20:05:591291 // Swaps contents with the `other` dictionary.
jdoerrie8e945542017-02-17 13:54:491292 void Swap(DictionaryValue* other);
[email protected]ec5263a2011-05-10 09:23:391293
[email protected]32c0e002011-11-08 21:26:411294 // This class provides an iterator over both keys and values in the
1295 // dictionary. It can't be used to modify the dictionary.
Daniel Cheng619653b2022-02-17 18:33:121296 //
1297 // DEPRECATED: Use a range-based for loop over `base::Value::Dict` directly
1298 // instead.
[email protected]a34cc092012-08-10 12:45:351299 class BASE_EXPORT Iterator {
[email protected]32c0e002011-11-08 21:26:411300 public:
[email protected]a34cc092012-08-10 12:45:351301 explicit Iterator(const DictionaryValue& target);
vmpstre65942b2016-02-25 00:50:311302 Iterator(const Iterator& other);
[email protected]a8d94b42013-12-10 18:52:221303 ~Iterator();
[email protected]32c0e002011-11-08 21:26:411304
Lei Zhang10fce02f2021-05-14 18:45:081305 bool IsAtEnd() const { return it_ == target_.DictItems().end(); }
[email protected]32c0e002011-11-08 21:26:411306 void Advance() { ++it_; }
1307
1308 const std::string& key() const { return it_->first; }
Lei Zhang10fce02f2021-05-14 18:45:081309 const Value& value() const { return it_->second; }
[email protected]32c0e002011-11-08 21:26:411310
1311 private:
1312 const DictionaryValue& target_;
Lei Zhang10fce02f2021-05-14 18:45:081313 detail::const_dict_iterator it_;
[email protected]32c0e002011-11-08 21:26:411314 };
1315
Daniel Cheng619653b2022-02-17 18:33:121316 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerriee964d9a2017-04-05 06:44:171317 // TODO(crbug.com/646113): Delete this and migrate callsites.
jdoerrie8e945542017-02-17 13:54:491318 DictionaryValue* DeepCopy() const;
Daniel Cheng619653b2022-02-17 18:33:121319 // DEPRECATED, use `Value::Dict::Clone()` instead.
jdoerried4b852612017-06-06 11:48:431320 // TODO(crbug.com/646113): Delete this and migrate callsites.
dcheng093de9b2016-04-04 21:25:511321 std::unique_ptr<DictionaryValue> CreateDeepCopy() const;
initial.commitd7cae122008-07-26 21:49:381322};
1323
1324// This type of Value represents a list of other Value values.
Daniel Cheng619653b2022-02-17 18:33:121325//
1326// DEPRECATED: prefer `base::Value::List`.
[email protected]0bea7252011-08-05 15:34:001327class BASE_EXPORT ListValue : public Value {
initial.commitd7cae122008-07-26 21:49:381328 public:
Jan Wilken Dörrie46992f022020-02-20 11:25:471329 using const_iterator = ListView::const_iterator;
1330 using iterator = ListView::iterator;
[email protected]a502bbe72011-01-07 18:06:451331
Gabriel Charetteb49d73a2021-05-05 20:05:591332 // Returns `value` if it is a list, nullptr otherwise.
dcheng093de9b2016-04-04 21:25:511333 static std::unique_ptr<ListValue> From(std::unique_ptr<Value> value);
reillyg259c0a32015-09-11 00:25:541334
[email protected]3a3d47472010-07-15 21:03:541335 ListValue();
Jan Wilken Dörrie53e009b2019-09-09 14:17:411336 explicit ListValue(span<const Value> in_list);
jdoerrie52939ed2017-04-26 18:19:421337 explicit ListValue(ListStorage&& in_list) noexcept;
initial.commitd7cae122008-07-26 21:49:381338
Gabriel Charetteb49d73a2021-05-05 20:05:591339 // Convenience forms of `Get()`. Modifies `out_value` (and returns true)
[email protected]35213ce92010-04-08 19:06:151340 // only if the index is valid and the Value at that index can be returned
1341 // in the specified form.
Gabriel Charetteb49d73a2021-05-05 20:05:591342 // `out_value` is optional and will only be set if non-NULL.
Daniel Cheng619653b2022-02-17 18:33:121343 //
1344 // DEPRECATED: prefer `Value::List::operator[]` + `GetIfDict()`.
[email protected]5d30f92bf2012-08-03 08:43:371345 bool GetDictionary(size_t index, const DictionaryValue** out_value) const;
1346 bool GetDictionary(size_t index, DictionaryValue** out_value);
jdoerrie52939ed2017-04-26 18:19:421347
initial.commitd7cae122008-07-26 21:49:381348 // Appends a Value to the end of the list.
Daniel Cheng619653b2022-02-17 18:33:121349 // DEPRECATED: prefer `Value::List::Append()`.
1350 using Value::Append;
Daniel Chengedfa5202022-04-15 00:09:591351 // DEPRECATED: prefer `Value::List::Append()`. Provided to simplify
1352 // incremental migration and intentionally only defined on ListValue and not
1353 // Value.
1354 void Append(base::Value::Dict in_dict);
1355 void Append(base::Value::List in_list);
initial.commitd7cae122008-07-26 21:49:381356
Gabriel Charetteb49d73a2021-05-05 20:05:591357 // Swaps contents with the `other` list.
Daniel Cheng619653b2022-02-17 18:33:121358 //
1359 // DEPRECATED: prefer `base::Value::List` + `std::swap()`.
jdoerrie8e945542017-02-17 13:54:491360 void Swap(ListValue* other);
[email protected]8b8e7c92010-08-19 18:05:561361
Daniel Cheng619653b2022-02-17 18:33:121362 // Iteration: Use a range-based for loop over `base::Value::List` directly
1363 // instead.
initial.commitd7cae122008-07-26 21:49:381364};
1365
Daniel Cheng8ac305b2022-02-17 00:05:111366// Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON
1367// serialization methods without having to clone the contents and transfer
1368// ownership of the clone to a `Value` wrapper object.
1369//
1370// Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any
1371// underlying object that is passed by reference (i.e. `std::string`,
1372// `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain
1373// live as long as there is a `ValueView` referencing it.
1374//
1375// While it might be nice to just use the `absl::variant` type directly, the
1376// need to use `std::reference_wrapper` makes it clunky. `absl::variant` and
1377// `std::reference_wrapper` both support implicit construction, but C++ only
1378// allows at most one user-defined conversion in an implicit conversion
1379// sequence. If this adapter and its implicit constructors did not exist,
1380// callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or
1381// `Value::List` to a function with a `ValueView` parameter.
1382class BASE_EXPORT GSL_POINTER ValueView {
1383 public:
1384 ValueView(bool value) : data_view_(value) {}
1385 ValueView(int value) : data_view_(value) {}
1386 ValueView(double value)
1387 : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {}
1388 ValueView(const std::string& value) : data_view_(value) {}
1389 ValueView(const Value::BlobStorage& value) : data_view_(value) {}
1390 ValueView(const Value::Dict& value) : data_view_(value) {}
1391 ValueView(const Value::List& value) : data_view_(value) {}
1392 ValueView(const Value& value);
1393
1394 template <typename Visitor>
1395 auto Visit(Visitor&& visitor) const {
1396 return absl::visit(std::forward<Visitor>(visitor), data_view_);
1397 }
1398
1399 private:
1400 using ViewType =
1401 absl::variant<absl::monostate,
1402 bool,
1403 int,
1404 Value::DoubleStorage,
1405 std::reference_wrapper<const std::string>,
1406 std::reference_wrapper<const Value::BlobStorage>,
1407 std::reference_wrapper<const Value::Dict>,
1408 std::reference_wrapper<const Value::List>>;
1409
1410 ViewType data_view_;
1411};
1412
prashhir54a994502015-03-05 09:30:571413// This interface is implemented by classes that know how to serialize
1414// Value objects.
[email protected]0bea7252011-08-05 15:34:001415class BASE_EXPORT ValueSerializer {
initial.commitd7cae122008-07-26 21:49:381416 public:
[email protected]3a3d47472010-07-15 21:03:541417 virtual ~ValueSerializer();
[email protected]abb9d0c2008-08-06 15:46:591418
Daniel Cheng8ac305b2022-02-17 00:05:111419 virtual bool Serialize(ValueView root) = 0;
prashhir54a994502015-03-05 09:30:571420};
1421
1422// This interface is implemented by classes that know how to deserialize Value
1423// objects.
1424class BASE_EXPORT ValueDeserializer {
1425 public:
1426 virtual ~ValueDeserializer();
initial.commitd7cae122008-07-26 21:49:381427
1428 // This method deserializes the subclass-specific format into a Value object.
[email protected]b4cebf82008-12-29 19:59:081429 // If the return value is non-NULL, the caller takes ownership of returned
Nigel Tao410788e2020-06-24 07:12:271430 // Value.
1431 //
Gabriel Charetteb49d73a2021-05-05 20:05:591432 // If the return value is nullptr, and if `error_code` is non-nullptr,
1433 // `*error_code` will be set to an integer value representing the underlying
Nigel Tao410788e2020-06-24 07:12:271434 // error. See "enum ErrorCode" below for more detail about the integer value.
1435 //
Gabriel Charetteb49d73a2021-05-05 20:05:591436 // If `error_message` is non-nullptr, it will be filled in with a formatted
[email protected]ba399672010-04-06 15:42:391437 // error message including the location of the error if appropriate.
dcheng093de9b2016-04-04 21:25:511438 virtual std::unique_ptr<Value> Deserialize(int* error_code,
Nigel Tao410788e2020-06-24 07:12:271439 std::string* error_message) = 0;
1440
1441 // The integer-valued error codes form four groups:
1442 // - The value 0 means no error.
1443 // - Values between 1 and 999 inclusive mean an error in the data (i.e.
1444 // content). The bytes being deserialized are not in the right format.
1445 // - Values 1000 and above mean an error in the metadata (i.e. context). The
1446 // file could not be read, the network is down, etc.
1447 // - Negative values are reserved.
Caitlin Fischeraac06dc2021-12-17 00:21:321448 //
1449 // These values are persisted to logs. Entries should not be renumbered and
1450 // numeric values should never be reused.
Nigel Tao410788e2020-06-24 07:12:271451 enum ErrorCode {
1452 kErrorCodeNoError = 0,
1453 // kErrorCodeInvalidFormat is a generic error code for "the data is not in
1454 // the right format". Subclasses of ValueDeserializer may return other
1455 // values for more specific errors.
1456 kErrorCodeInvalidFormat = 1,
1457 // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the
1458 // range of metadata errors.
1459 kErrorCodeFirstMetadataError = 1000,
1460 };
1461
Gabriel Charetteb49d73a2021-05-05 20:05:591462 // The `error_code` argument can be one of the ErrorCode values, but it is
Nigel Tao410788e2020-06-24 07:12:271463 // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer
1464 // can define their own error code values.
1465 static inline bool ErrorCodeIsDataError(int error_code) {
1466 return (kErrorCodeInvalidFormat <= error_code) &&
1467 (error_code < kErrorCodeFirstMetadataError);
1468 }
initial.commitd7cae122008-07-26 21:49:381469};
1470
Daniel Chenga367fe52022-02-15 18:08:481471// Stream operator so Values can be pretty printed by gtest.
[email protected]e4ef8312012-09-12 03:39:351472BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value);
Daniel Chenga367fe52022-02-15 18:08:481473BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1474 const Value::Dict& dict);
1475BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1476 const Value::List& list);
[email protected]e4ef8312012-09-12 03:39:351477
Daniel Chenga367fe52022-02-15 18:08:481478// Hints for DictionaryValue and ListValue; otherwise, gtest tends to prefer the
1479// default template implementation over an upcast to Value.
[email protected]ea0ec052013-04-16 09:04:021480BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
[email protected]ea0ec052013-04-16 09:04:021481 const DictionaryValue& value) {
1482 return out << static_cast<const Value&>(value);
1483}
1484
1485BASE_EXPORT inline std::ostream& operator<<(std::ostream& out,
1486 const ListValue& value) {
1487 return out << static_cast<const Value&>(value);
1488}
1489
jdoerriedc72ee942016-12-07 15:43:281490// Stream operator so that enum class Types can be used in log statements.
1491BASE_EXPORT std::ostream& operator<<(std::ostream& out,
1492 const Value::Type& type);
1493
[email protected]f3a1c642011-07-12 19:15:031494} // namespace base
1495
[email protected]101d5422008-09-26 20:22:421496#endif // BASE_VALUES_H_