Provide bespoke types for dictionaries and lists of base::Values.
The proposal for updating base::Value to a value type flattened the
convenience APIs for working with dictionaries and lists directly into
base::Value. In addition, it was believed that most code working with
dictionaries and lists could be directly use the underlying types
(base::flat_map<std::string, base::Value> and std::vector<base::Value>)
instead.
However, the migration to the updated API has resulted in several
non-optimal outcomes:
- Using the raw container types directly leads to bloat in the generated
code due to the required repetition of boilerplate code.
- Using the flattened base::Value convenience methods leads to a loss in
type safety: code that is only using a base::Value to use the
dictionary methods now relies on runtime checks to ensure that
incorrect inputs are not supplied.
- Exposing the raw container types makes it harder to refactor
implementation details in the future.
This CL reimplements distinct types for dictionaries and lists of
base::Values and updates base::Value to use these new types as the
internal representation. With the exception of APIs slated for removal,
many of the flattened APIs have already been migrated to internally use
the updated implementation as well.
Additional changes in this CL:
- Methods that work directly with the various subtypes now consistently
act on the same set of overloads (with the exception of constructors
for legacy reasons).
- Dictionary APIs that work with keys no longer have a 'Key' suffix.
- Dictionary APIs that work with paths now have a 'ByDottedPath' suffix
instead. There is fairly consistent, yet unnecessary, use of the path
methods; hopefully, the new, more verbose, suffix will make it clear
that special processing happens for paths.
- Dictionary APIs that work with paths now enforce a consistent set of
rules. Previously, empty paths were sometimes allowed, but empty paths
are never allowed now.
- A hack to allow JSON serialization to work with the new dictionary and
list subtypes without requiring that they be cloned into a base::Value
wrapper. A followup will implement a proper view type for base::Value
to enable these use cases without code duplication.
Bug: 1291666, 1291670
Change-Id: Ie5361449d67a66de48756c1049015dd09464543d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3443197
Reviewed-by: Finnur Thorarinsson <[email protected]>
Reviewed-by: Pavol Marko <[email protected]>
Reviewed-by: Gabriel Charette <[email protected]>
Reviewed-by: Nektarios Paisios <[email protected]>
Reviewed-by: Jan Wilken Dörrie <[email protected]>
Commit-Queue: Daniel Cheng <[email protected]>
Cr-Commit-Position: refs/heads/main@{#971315}
diff --git a/base/value_iterators.h b/base/value_iterators.h
index 92f7357..6081c6b 100644
--- a/base/value_iterators.h
+++ b/base/value_iterators.h
@@ -62,6 +62,14 @@
BASE_EXPORT friend bool operator!=(const dict_iterator& lhs,
const dict_iterator& rhs);
+ // Currently, there is no easy way to friend Value::Dict. Once dictionary
+ // storage is updated to not require a proxy iterator, the implementation can
+ // be folded into //base/values.h and a standard friend declaration can be
+ // used instead.
+ const DictStorage::iterator& GetUnderlyingIteratorDoNotUse() {
+ return dict_iter_;
+ }
+
private:
DictStorage::iterator dict_iter_;
};
@@ -108,6 +116,14 @@
BASE_EXPORT friend bool operator!=(const const_dict_iterator& lhs,
const const_dict_iterator& rhs);
+ // Currently, there is no easy way to friend Value::Dict. Once dictionary
+ // storage is updated to not require a proxy iterator, the implementation can
+ // be folded into //base/values.h and a standard friend declaration can be
+ // used instead.
+ const DictStorage::const_iterator& GetUnderlyingIteratorDoNotUse() {
+ return dict_iter_;
+ }
+
private:
DictStorage::const_iterator dict_iter_;
};